Пример #1
0
def find_and_fit_edges(data, header, bs, options, edgeThreshold=450):
    '''
    Given a flat field image, find_and_fit_edges determines the position
    of all slits.

    The function works by starting with a guess at the location for a slit
    edge in the spatial direction(options["first-slit-edge"]). 
    
    Starting from the guess, find_edge_pair works out in either direction, 
    measuring the position of the (e.g.) bottom of slit 1 and top of slit 2:


    ------ pixel y value = 2048

    Slit 1 data

    ------ (bottom)
    deadband
    ------ (top)

    Slit N pixel data ....

    ------- (bottom) pixel = 0

    --------------------------------> Spectral direction


    1. At the top of the flat, the slit edge is defined to be a pixel value
    2. The code guesses the position of the bottom of the slit, and runs
            find_edge_pair to measure slit edge locations.
    3. A low-order polynomial is fit to the edge locations with
            fit_edge_poly
    4. The top and bottom of the current slit, is stored into the
            result list.
    5. The top of the next slit is stored temporarily for the next
            iteration of the for loop.
    6. At the bottom of the flat, the slit edge is defined to be pixel 4.


    options:
    options["edge-order"] -- The order of the polynomial [pixels] edge.
    options["edge-fit-width"] -- The length [pixels] of the edge to 
            fit over

    '''

    # TODO: move hardcoded values into Options.py
    # y is the location to start
    y = 2034
    DY = 44.25

    toc = 0
    ssl = bs.ssl

    slits = []

    top = [0., np.float(Options.npix)]

    start_slit_num = int(bs.msl[0]['Slit_Number']) - 1
    if start_slit_num > 0:
        y -= DY * start_slit_num

    # Count and check that the # of objects in the SSL matches that of the MSL
    # This is purely a safety check
    numslits = np.zeros(len(ssl))
    for i in xrange(len(ssl)):
        slit = ssl[i]
        M = np.where(slit["Target_Name"] == bs.msl["Target_in_Slit"])

        numslits[i] = len(M[0])
    numslits = np.array(numslits)

    if (np.sum(numslits) != CSU.numslits) and (not bs.long_slit) and (
            not bs.long2pos_slit) and (not bs.long2pos_slit_specphot):
        error("The number of allocated CSU slits (%i) does not match "
              " the number of possible slits (%i)." %
              (np.sum(numslits), CSU.numslits))
        raise Exception(
            "The number of allocated CSU slits (%i) does not match "
            " the number of possible slits (%i)." %
            (np.sum(numslits), CSU.numslits))

    # if the mask is a long slit, the default y value will be wrong. Set instead to be the middle
    if bs.long_slit:
        y = 1104

    # now begin steps outline above
    results = []
    result = {}

    result["Target_Name"] = ssl[0]["Target_Name"]

    # 1
    result["top"] = np.poly1d([y])
    ''' Nomenclature here is confusing:
        
        ----- Edge  -- Top of current slit, bottom of prev slit
        . o ' Data
        ===== Data
        .;.;' Data
        ----- Edge  -- Bottom of current slit, top of next slit
    '''

    topfun = np.poly1d([y])
    xposs_top_this = np.arange(10, 2000, 100)
    yposs_top_this = topfun(xposs_top_this)

    for target in xrange(len(ssl)):

        y -= DY * numslits[target]
        y = max(y, 1)

        info("%2.2i] Finding Slit Edges for %s ending at %4.0i. Slit "
             "composed of %i CSU slits" %
             (target, ssl[target]["Target_Name"], y, numslits[target]))
        ''' First deal with the current slit '''
        hpps = Wavelength.estimate_half_power_points(
            bs.scislit_to_csuslit(target + 1)[0], header, bs)

        if y == 1:
            xposs_bot = [1024]
            xposs_bot_missing = []
            yposs_bot = [4.25]
            botfun = np.poly1d(yposs_bot)
            ok = np.where((xposs_bot > hpps[0]) & (xposs_bot < hpps[1]))
        else:
            (xposs_top_next, xposs_top_next_missing, yposs_top_next, xposs_bot,
             xposs_bot_missing, yposs_bot,
             scatter_bot_this) = find_edge_pair(data,
                                                y,
                                                options["edge-fit-width"],
                                                edgeThreshold=edgeThreshold)

            ok = np.where((xposs_bot > hpps[0]) & (xposs_bot < hpps[1]))
            ok2 = np.where((xposs_bot_missing > hpps[0])
                           & (xposs_bot_missing < hpps[1]))
            xposs_bot = xposs_bot[ok]
            xposs_bot_missing = xposs_bot_missing[ok2]
            yposs_bot = yposs_bot[ok]
            if len(xposs_bot) == 0:
                botfun = np.poly1d(y - DY)
            else:
                (botfun, bot_res, botsd,
                 botok) = fit_edge_poly(xposs_bot, xposs_bot_missing,
                                        yposs_bot, options["edge-order"])

        bot = botfun.c.copy()
        top = topfun.c.copy()

        #4
        result = {}
        result["Target_Name"] = ssl[target]["Target_Name"]
        result["xposs_top"] = xposs_top_this
        result["yposs_top"] = yposs_top_this
        result["xposs_bot"] = xposs_bot
        result["yposs_bot"] = yposs_bot
        result["top"] = np.poly1d(top)
        result["bottom"] = np.poly1d(bot)
        result["hpps"] = hpps
        result["ok"] = ok
        results.append(result)

        #5
        if y == 1:
            break

        next = target + 2
        if next > len(ssl): next = len(ssl)
        hpps_next = Wavelength.estimate_half_power_points(
            bs.scislit_to_csuslit(next)[0], header, bs)

        ok = np.where((xposs_top_next > hpps_next[0])
                      & (xposs_top_next < hpps_next[1]))
        ok2 = np.where((xposs_top_next_missing > hpps_next[0])
                       & (xposs_top_next_missing < hpps_next[1]))

        xposs_top_next = xposs_top_next[ok]
        xposs_top_next_missing = xposs_top_next_missing[ok2]
        yposs_top_next = yposs_top_next[ok]

        if len(xposs_top_next) == 0:
            topfun = np.poly1d(y)
        else:
            (topfun, topres, topsd,
             ok) = fit_edge_poly(xposs_top_next, xposs_top_next_missing,
                                 yposs_top_next, options["edge-order"])

        xposs_top_this = xposs_top_next
        xposs_top_this_missing = xposs_top_next_missing
        yposs_top_this = yposs_top_next

    results.append({"version": options["version"]})

    return results
Пример #2
0
def find_and_fit_edges(data, header, bs, options,edgeThreshold=450):
    '''
    Given a flat field image, find_and_fit_edges determines the position
    of all slits.

    The function works by starting with a guess at the location for a slit
    edge in the spatial direction(options["first-slit-edge"]). 
    
    Starting from the guess, find_edge_pair works out in either direction, 
    measuring the position of the (e.g.) bottom of slit 1 and top of slit 2:


    ------ pixel y value = 2048

    Slit 1 data

    ------ (bottom)
    deadband
    ------ (top)

    Slit N pixel data ....

    ------- (bottom) pixel = 0

    --------------------------------> Spectral direction


    1. At the top of the flat, the slit edge is defined to be a pixel value
    2. The code guesses the position of the bottom of the slit, and runs
            find_edge_pair to measure slit edge locations.
    3. A low-order polynomial is fit to the edge locations with
            fit_edge_poly
    4. The top and bottom of the current slit, is stored into the
            result list.
    5. The top of the next slit is stored temporarily for the next
            iteration of the for loop.
    6. At the bottom of the flat, the slit edge is defined to be pixel 4.


    options:
    options["edge-order"] -- The order of the polynomial [pixels] edge.
    options["edge-fit-width"] -- The length [pixels] of the edge to 
            fit over

    '''

    # TODO: move hardcoded values into Options.py
    # y is the location to start
    y = 2034
    DY = 44.25

    toc = 0
    ssl = bs.ssl

    slits = []

    top = [0., np.float(Options.npix)]

    start_slit_num = int(bs.msl[0]['Slit_Number'])-1
    if start_slit_num > 0:
        y -= DY * start_slit_num

    # Count and check that the # of objects in the SSL matches that of the MSL
    # This is purely a safety check
    numslits = np.zeros(len(ssl))
    for i in xrange(len(ssl)):
        slit = ssl[i]
        M = np.where(slit["Target_Name"] == bs.msl["Target_in_Slit"])

        numslits[i] = len(M[0])
    numslits = np.array(numslits)


    if (np.sum(numslits) != CSU.numslits) and (not bs.long_slit) and (not bs.long2pos_slit) and (not bs.long2pos_slit_specphot):
        error ("The number of allocated CSU slits (%i) does not match "
                " the number of possible slits (%i)." % (np.sum(numslits),
                    CSU.numslits))
        raise Exception("The number of allocated CSU slits (%i) does not match "
                " the number of possible slits (%i)." % (np.sum(numslits),
                    CSU.numslits))

    # if the mask is a long slit, the default y value will be wrong. Set instead to be the middle
    if bs.long_slit:
        y = 1104
        
    # now begin steps outline above
    results = []
    result = {}

    result["Target_Name"] = ssl[0]["Target_Name"]

    # 1
    result["top"] = np.poly1d([y])

    ''' Nomenclature here is confusing:
        
        ----- Edge  -- Top of current slit, bottom of prev slit
        . o ' Data
        ===== Data
        .;.;' Data
        ----- Edge  -- Bottom of current slit, top of next slit
    '''

    topfun = np.poly1d([y])
    xposs_top_this = np.arange(10,2000,100)
    yposs_top_this = topfun(xposs_top_this)

    for target in xrange(len(ssl)):

        y -= DY * numslits[target]
        y = max(y, 1)
        
        info("%2.2i] Finding Slit Edges for %s ending at %4.0i. Slit "
                "composed of %i CSU slits" % ( target,
                    ssl[target]["Target_Name"], y, numslits[target]))

        ''' First deal with the current slit '''
        hpps = Wavelength.estimate_half_power_points(
                bs.scislit_to_csuslit(target+1)[0], header, bs)

        if y == 1:
            xposs_bot = [1024]
            xposs_bot_missing = []
            yposs_bot = [4.25]
            botfun = np.poly1d(yposs_bot)
            ok = np.where((xposs_bot > hpps[0]) & (xposs_bot < hpps[1]))
        else:
            (xposs_top_next, xposs_top_next_missing, yposs_top_next, xposs_bot,
                xposs_bot_missing, yposs_bot, scatter_bot_this) = find_edge_pair(
                    data, y, options["edge-fit-width"],edgeThreshold=edgeThreshold)

            ok = np.where((xposs_bot > hpps[0]) & (xposs_bot < hpps[1]))
            ok2 = np.where((xposs_bot_missing > hpps[0]) & (xposs_bot_missing <
                hpps[1]))
            xposs_bot = xposs_bot[ok]
            xposs_bot_missing = xposs_bot_missing[ok2]
            yposs_bot = yposs_bot[ok]
            if len(xposs_bot) == 0:
                botfun = np.poly1d(y-DY)
            else:
                (botfun, bot_res, botsd, botok) =  fit_edge_poly(xposs_bot,
                         xposs_bot_missing, yposs_bot, options["edge-order"])


        bot = botfun.c.copy() 
        top = topfun.c.copy()

        #4
        result = {}
        result["Target_Name"] = ssl[target]["Target_Name"]
        result["xposs_top"] = xposs_top_this
        result["yposs_top"] = yposs_top_this
        result["xposs_bot"] = xposs_bot
        result["yposs_bot"] = yposs_bot
        result["top"] = np.poly1d(top)
        result["bottom"] = np.poly1d(bot)
        result["hpps"] = hpps
        result["ok"] = ok
        results.append(result)

        #5
        if y == 1:
            break
            

        next = target + 2
        if next > len(ssl): next = len(ssl)
        hpps_next = Wavelength.estimate_half_power_points(
                bs.scislit_to_csuslit(next)[0],
                    header, bs)

        ok = np.where((xposs_top_next > hpps_next[0]) & (xposs_top_next <
            hpps_next[1]))
        ok2 = np.where((xposs_top_next_missing > hpps_next[0]) &
            (xposs_top_next_missing < hpps_next[1]))

        xposs_top_next = xposs_top_next[ok]
        xposs_top_next_missing = xposs_top_next_missing[ok2]
        yposs_top_next = yposs_top_next[ok]

        if len(xposs_top_next) == 0:
            topfun = np.poly1d(y)
        else:
            (topfun, topres, topsd, ok) = fit_edge_poly(xposs_top_next,
                xposs_top_next_missing, yposs_top_next, options["edge-order"])

        xposs_top_this = xposs_top_next
        xposs_top_this_missing = xposs_top_next_missing
        yposs_top_this = yposs_top_next

    results.append({"version": options["version"]})

    return results
Пример #3
0
def find_longslit_edges(data,
                        header,
                        bs,
                        options,
                        edgeThreshold=450,
                        longslit=None):

    y = 2034
    DY = 44.25

    toc = 0
    ssl = bs.ssl

    slits = []

    top = [0., np.float(Options.npix)]

    start_slit_num = int(bs.msl[0]['Slit_Number']) - 1
    if start_slit_num > 0:
        y -= DY * start_slit_num
    # if the mask is a long slit, the default y value will be wrong. Set instead to be the middle
    if bs.long_slit:
        try:
            y = longslit["yrange"][1]
        except:
            error(
                "Longslit reduction mode is specified, but the row position has not been specified. Defaulting to "
                + str(y))
            print "Longslit reduction mode is specified, but the row position has not been specified. Defaulting to " + str(
                y)

    # Count and check that the # of objects in the SSL matches that of the MSL
    # This is purely a safety check
    numslits = np.zeros(len(ssl))
    for i in xrange(len(ssl)):
        slit = ssl[i]
        M = np.where(slit["Target_Name"] == bs.msl["Target_in_Slit"])

        numslits[i] = len(M[0])
    numslits = np.array(numslits)
    info("Number of slits allocated for this longslit: " +
         str(np.sum(numslits)))

    # now begin steps outline above
    results = []
    result = {}

    result["Target_Name"] = ssl[0]["Target_Name"]

    # 1 Defines a polynomial of degree 0, which is a constant, with the value of the top of the slit
    result["top"] = np.poly1d([longslit["yrange"][1]])

    topfun = np.poly1d([longslit["yrange"][1]
                        ])  # this is a constant funtion with c=top of the slit
    botfun = np.poly1d([
        longslit["yrange"][0]
    ])  # this is a constant funtion with c=bottom of the slit

    # xposs_top_this = [10 110 210 .... 1810 1910]
    xposs_top = np.arange(10, 2000, 100)
    xposs_bot = np.arange(10, 2000, 100)
    # yposs_top_this = [1104 1104 ... 1104 1104], it's the constant polynomium calculated at the X positions
    yposs_top = topfun(xposs_top)
    yposs_bot = botfun(xposs_bot)
    ''' Deal with the current slit '''
    target = 0
    hpps = Wavelength.estimate_half_power_points(
        bs.scislit_to_csuslit(target + 1)[0], header, bs)

    ok = np.where((xposs_top > hpps[0]) & (xposs_top < hpps[1]))

    xposs_bot = xposs_bot[ok]
    yposs_bot = yposs_bot[ok]
    xposs_top = xposs_top[ok]
    yposs_top = yposs_top[ok]

    if len(xposs_bot) == 0:
        error("The slit edges specifications appear to be incorrect.")
        raise Exception(
            "The slit edges specifications appear to be incorrect.")

    # bot is the polynomium that defines the shape of the bottom of the slit. In this case, we set it to a constant.
    bot = botfun.c.copy()
    top = topfun.c.copy()

    #4
    result = {}
    result["Target_Name"] = ssl[target]["Target_Name"]
    result["xposs_top"] = xposs_top
    result["yposs_top"] = yposs_top
    result["xposs_bot"] = xposs_bot
    result["yposs_bot"] = yposs_bot
    result["top"] = np.poly1d(top)
    result["bottom"] = np.poly1d(bot)
    result["hpps"] = hpps
    result["ok"] = ok
    results.append(result)

    results.append({"version": options["version"]})

    return results
Пример #4
0
def find_longslit_edges(data, header, bs, options, edgeThreshold=450,longslit=None):


    y = 2034
    DY = 44.25


    toc = 0
    ssl = bs.ssl

    slits = []

    top = [0., np.float(Options.npix)]

    start_slit_num = int(bs.msl[0]['Slit_Number'])-1
    if start_slit_num > 0:
        y -= DY * start_slit_num
    # if the mask is a long slit, the default y value will be wrong. Set instead to be the middle
    if bs.long_slit:
        try:
            y=longslit["yrange"][1]
        except:
            error("Longslit reduction mode is specified, but the row position has not been specified. Defaulting to "+str(y))
            print "Longslit reduction mode is specified, but the row position has not been specified. Defaulting to "+str(y)


    # Count and check that the # of objects in the SSL matches that of the MSL
    # This is purely a safety check
    numslits = np.zeros(len(ssl))
    for i in xrange(len(ssl)):
        slit = ssl[i]
        M = np.where(slit["Target_Name"] == bs.msl["Target_in_Slit"])

        numslits[i] = len(M[0])
    numslits = np.array(numslits)
    info("Number of slits allocated for this longslit: "+str(np.sum(numslits)))

    # now begin steps outline above
    results = []
    result = {}

    result["Target_Name"] = ssl[0]["Target_Name"]

    # 1 Defines a polynomial of degree 0, which is a constant, with the value of the top of the slit
    result["top"] = np.poly1d([longslit["yrange"][1]])
    
    topfun = np.poly1d([longslit["yrange"][1]]) # this is a constant funtion with c=top of the slit
    botfun = np.poly1d([longslit["yrange"][0]]) # this is a constant funtion with c=bottom of the slit

    # xposs_top_this = [10 110 210 .... 1810 1910]
    xposs_top = np.arange(10,2000,100)
    xposs_bot = np.arange(10,2000,100)
    # yposs_top_this = [1104 1104 ... 1104 1104], it's the constant polynomium calculated at the X positions
    yposs_top = topfun(xposs_top)
    yposs_bot = botfun(xposs_bot)

    
    ''' Deal with the current slit '''
    target=0
    hpps = Wavelength.estimate_half_power_points(
                bs.scislit_to_csuslit(target+1)[0], header, bs)

    ok = np.where((xposs_top > hpps[0]) & (xposs_top < hpps[1]))

    xposs_bot = xposs_bot[ok]
    yposs_bot = yposs_bot[ok]
    xposs_top = xposs_top[ok]
    yposs_top = yposs_top[ok]

    if len(xposs_bot) == 0:
        error ("The slit edges specifications appear to be incorrect.")
        raise Exception("The slit edges specifications appear to be incorrect.")

    # bot is the polynomium that defines the shape of the bottom of the slit. In this case, we set it to a constant.
    bot = botfun.c.copy() 
    top = topfun.c.copy()


    #4
    result = {}
    result["Target_Name"] = ssl[target]["Target_Name"]
    result["xposs_top"] = xposs_top
    result["yposs_top"] = yposs_top
    result["xposs_bot"] = xposs_bot
    result["yposs_bot"] = yposs_bot
    result["top"] = np.poly1d(top)
    result["bottom"] = np.poly1d(bot)
    result["hpps"] = hpps
    result["ok"] = ok
    results.append(result)

    results.append({"version": options["version"]})

    return results