Beispiel #1
0
def calc_EQ_Jacobian_dgs(*args):
    """
    This function calculates the area of a polygon for use in the application
    of the Jacobian for DGS S(Q,E) data.

    @param args: A list of parameters used to calculate the area

    The following is a list of the arguments needed in their expected order
      1. E_1
      2. Q_1
      3. E_2
      4. Q_2
      5. E_3
      6. Q_3
      7. E_4
      8. Q_4
    @type args: C{list}
    
    
    @return: The polygon areas
    @rtype: (C{nessi_list.NessiList}, C{nessi_list.NessiList})
    """
    import nessi_list
    import utils

    # Settle out the arguments to sensible names
    E1 = args[0]
    Q1 = args[1]
    E2 = args[2]
    Q2 = args[3]
    E3 = args[4]
    Q3 = args[5]
    E4 = args[6]
    Q4 = args[7]

    poly_size = 4

    area = nessi_list.NessiList(len(E1))
    area_err2 = nessi_list.NessiList(len(E1))

    import itertools
    xvals = [xvals for xvals in itertools.izip(E1, E2, E3, E4, E1, E2)]
    yvals = [yvals for yvals in itertools.izip(Q1, Q2, Q3, Q4, Q1, Q2)]
    for x, y, i in itertools.izip(xvals, yvals, itertools.count()):
        xn = nessi_list.NessiList()
        xn.extend(x)
        yn = nessi_list.NessiList()
        yn.extend(y)
        area[i] = utils.calc_area_2D_polygon(xn, yn, poly_size)

    return (area, area_err2)
Beispiel #2
0
def ref_beamdiv_correct(attrs, pix_id, epsilon, cpix, **kwargs):
    """

    @param attrs: The attribute list of a C{SOM.SOM}
    @type attrs: C{SOM.AttributeList}

    @param pix_id: The pixel ID for which the correction will be calculated
    @type pix_id: C{tuple}

    @param epsilon: The pixel spatial resolution in units of meters
    @type epsilon: C{float}

    @param cpix: The center pixel for the calculation
    @type cpix: C{float}

    @param kwargs: A list of keyword arguments that the function accepts:

    @kwarg det_secondary: The main sample to detector flightpath in meters.
    @type det_secondary: C{float}

    @kwarg pix_width: The width of a pixel in the high resolution direction
    @type pix_width: C{float}


    @return: The beam divergence correction to the scattering angle
    @type: float

    @raise RuntimeError: If the instrument name is not recognized.
    """
    # Set instrument specific strings
    inst_name = attrs["instrument_name"]
    if inst_name == "REF_L":
        first_slit_size = "data-slit1_size"
        last_slit_size = "data-slit2_size"
        last_slit_dist = "data-slit2_distance"
        slit_dist = "data-slit12_distance"

    elif inst_name == "REF_M":
        first_slit_size = "data-slit1_size"
        last_slit_size = "data-slit3_size"
        last_slit_dist = "data-slit3_distance"
        slit_dist = "data-slit13_distance"
    else:
        raise RuntimeError("Do not know how to handle instrument %s" \
                           % inst_name)

    # Get sorting direction, y is True, x is False
    y_sort = attrs["ref_sort"]
    
    # Get keyword arguments
    det_secondary = kwargs.get("det_secondary")
    pix_width = kwargs.get("pix_width")

    # Check keyword arguments
    if det_secondary is None:
        det_secondary = attrs.instrument.get_det_secondary()[0]

    # This is currently set to the same number for both REF_L and REF_M
    if epsilon is None:
        epsilon = 0.5 * 1.3 * 1.0e-3

    # Set the center pixel to something
    if cpix is None:
        cpix = 133.5

    gamma_plus = math.atan2(0.5 * (attrs[first_slit_size][0] + \
                                   attrs[last_slit_size][0]),
                            attrs[slit_dist][0])
    
    gamma_minus = math.atan2(0.5 * (attrs[first_slit_size][0] - \
                                    attrs[last_slit_size][0]),
                             attrs[slit_dist][0])

    half_last_aperture = 0.5 * attrs[last_slit_size][0]
    neg_half_last_aperture = -1.0 * half_last_aperture

    last_slit_to_det = attrs[last_slit_dist][0] + det_secondary

    dist_last_aper_det_sin_gamma_plus = last_slit_to_det * math.sin(gamma_plus)
    dist_last_aper_det_sin_gamma_minus = last_slit_to_det * \
                                         math.sin(gamma_minus)

    # Set the delta theta coordinates of the acceptance polygon
    accept_poly_x = nessi_list.NessiList()
    accept_poly_x.append(-1.0 * gamma_minus)
    accept_poly_x.append(gamma_plus)
    accept_poly_x.append(gamma_plus)
    accept_poly_x.append(gamma_minus)
    accept_poly_x.append(-1.0 * gamma_plus)
    accept_poly_x.append(-1.0 * gamma_plus)
    accept_poly_x.append(accept_poly_x[0])

    # Set the z coordinates of the acceptance polygon
    accept_poly_y = nessi_list.NessiList()
    accept_poly_y.append(half_last_aperture - \
                         dist_last_aper_det_sin_gamma_minus + epsilon)
    accept_poly_y.append(half_last_aperture + \
                         dist_last_aper_det_sin_gamma_plus + epsilon)
    accept_poly_y.append(half_last_aperture + \
                         dist_last_aper_det_sin_gamma_plus - epsilon)
    accept_poly_y.append(neg_half_last_aperture + \
                         dist_last_aper_det_sin_gamma_minus - epsilon)
    accept_poly_y.append(neg_half_last_aperture - \
                         dist_last_aper_det_sin_gamma_plus - epsilon)
    accept_poly_y.append(neg_half_last_aperture - \
                         dist_last_aper_det_sin_gamma_plus + epsilon)
    accept_poly_y.append(accept_poly_y[0])

    if y_sort:
        cur_index = pix_id[1][1]
        if pix_width is None:
            cur_offset = attrs.instrument.get_y_pix_offset(pix_id)
            next_id = (pix_id[0], (pix_id[1][0], pix_id[1][1]+1))
            next_offset = attrs.instrument.get_y_pix_offset(next_id)
    else:
        cur_index = pix_id[1][0]
        if pix_width is None:
            cur_offset = attrs.instrument.get_x_pix_offset(pix_id)
            next_id = (pix_id[0], (pix_id[1][0]+1, pix_id[1][1]))
            next_offset = attrs.instrument.get_x_pix_offset(next_id)

    if pix_width is None:
        pix_width = math.fabs(next_offset - cur_offset)

    # Set the z band for the pixel
    xMinus = (cur_index - cpix - 0.5) * pix_width
    xPlus = (cur_index - cpix + 0.5) * pix_width

    # Calculate the intersection
    yLeftCross = -1
    yRightCross = -1

    xI = accept_poly_x[0]
    yI = accept_poly_y[0]

    int_poly_x = nessi_list.NessiList()
    int_poly_y = nessi_list.NessiList()

    for i in xrange(len(accept_poly_x)):
        xF = accept_poly_y[i]
        yF = accept_poly_x[i]

        if xI < xF:
            if xI < xMinus and xF >= xMinus:
                yLeftCross = yI + (yF - yI) * (xMinus - xI) / (xF - xI)
                int_poly_x.append(yLeftCross)
                int_poly_y.append(xMinus)

            if xI < xPlus and xF >= xPlus:
                yRightCross = yI + (yF - yI) * (xPlus - xI) / (xF - xI);
                int_poly_x.append(yRightCross)
                int_poly_y.append(xPlus)
                
        else:
            if xF < xPlus and xI >= xPlus:
                yRightCross = yI + (yF - yI) * (xPlus - xI) / (xF - xI);
                int_poly_x.append(yRightCross)
                int_poly_y.append(xPlus)

            if xF < xMinus and xI >= xMinus:
                yLeftCross = yI + (yF - yI) * (xMinus - xI) / (xF - xI);
                int_poly_x.append(yLeftCross)
                int_poly_y.append(xMinus)
                
        # This catches points on the polygon inside the range of interest
        if xF >= xMinus and xF < xPlus:
            int_poly_x.append(yF)
            int_poly_y.append(xF)

        xI = xF
        yI = yF

    if len(int_poly_x) > 2:
        int_poly_x.append(int_poly_x[0])
        int_poly_y.append(int_poly_y[0])
        int_poly_x.append(int_poly_x[1])
        int_poly_y.append(int_poly_y[1])
    else:
        # Intersection polygon is NULL, point or line, so has no area
        # Therefore there is no angle correction
        return None

    # Calculate intersection polygon aread
    import utils
    area = utils.calc_area_2D_polygon(int_poly_x, int_poly_y,
                                      len(int_poly_x) - 2, True)

    return __calc_center_of_mass(int_poly_x, int_poly_y, area)