Пример #1
0
def create_X_vs_pixpos(som, *args, **kwargs):
    """
    This function takes a group of single spectrum with any given axes
    (wavelength, energy etc.) and rebins those axes to the given axis and
    converts the spectra into a single I{I(X, pixel)} spectrum.

    @param som: The input object with arbitrary (but same) axis spectra
    @type som: C{SOM.SOM}
    
    @param args: A mandatory list of axes for rebinning.  There is a particular
                 order to them. They should be present in the following order:
    
                 Without errors
                   1. Axis
                 With errors
                   1. Axis
                   2. Axis error^2
    @type args: C{nessi_list.NessiList}s
    
    @param kwargs: A list of keyword arguments that the function accepts:
    
    @keyword withXVar: A flag for whether the function should be expecting the
                       associated axes to have errors. The default value will
                       be I{False}.
    @type withXVar: C{boolean}

    @keyword data_type: The name of the data type which can be either
                        I{histogram}, I{density} or I{coordinate}. The default
                        value will be I{histogram}.
    @type data_type: C{string}
    
    @keyword so_id: The identifier represents a number, string, tuple or other
                    object that describes the resulting C{SO}.
    @type so_id: C{int}, C{string}, C{tuple}, C{pixel ID}
    
    @keyword y_label: The dependent axis label
    @type y_label: C{string}
    
    @keyword y_units: The dependent axis units
    @type y_units: C{string}
    
    @keyword x_label: The second primary axis label
    @type x_label: C{string}
    
    @keyword x_units: The second primary axis units
    @type x_units: C{string}

    @keyword rebin: A flag for turning rebin on or off. The default is I{True}.
    @type rebin: C{boolean}


    @return: Object with a single 2D C{SO} with the given axis and global pixel
             position
    @rtype: C{SOM.SOM}


    @raise RuntimeError: The parameter given to the keyword argument withXVar
                         is not I{True} or I{False}
                         
    @raise RuntimeError: The parameter given to the keyword argument data_type
                         is not I{histogram} or I{density} or I{coordinate}.
                         
    @raise RuntimeError: The number of given arguments (x-axes) is not either 2
                         (no errors) or 4 (with errors)
    """

    import common_lib
    import nessi_list

    # Setup some variables 
    dim = 2
    N_y = []
    N_tot = 1
    N_args = len(args)

    # Check withXVar keyword argument and also check number of given args.
    # Set xvar to the appropriate value
    try:
        value = kwargs["withXVar"]
        if value.lower() == "true":
            if N_args != 2:
                raise RuntimeError("Since you have requested x errors, 2 x "\
                                   +"axes must be provided.")
            else:
                xvar = True
        elif value.lower() == "false":
            if N_args != 2:
                raise RuntimeError("Since you did not requested x errors, 2 "\
                                   +"x axes must be provided.")
            else:
                xvar = False
        else:
            raise RuntimeError("Do not understand given parameter %s" % \
                               value)
    except KeyError:
        if N_args != 1:
            raise RuntimeError("Since you did not requested x errors, 1 "\
                               +"x axes must be provided.")
        else:
            xvar = False

    # Check dataType keyword argument. An offset will be set to 1 for the
    # histogram type and 0 for either density or coordinate
    try:
        data_type = kwargs["data_type"]
        if data_type.lower() == "histogram":
            offset = 1
        elif data_type.lower() == "density" or \
                 data_type.lower() == "coordinate":
            offset = 0
        else:
            raise RuntimeError("Do not understand data type given: %s" % \
                               data_type)
    # Default is offset for histogram
    except KeyError:
        offset = 1

    so_dim = SOM.SO(dim)

    arb_axis = 1
    pixel_axis = 0

    # Set the x-axis arguments from the *args list into the new SO
    if not xvar:
        so_dim.axis[arb_axis].val = args[0]
    else:
        so_dim.axis[arb_axis].val = args[0]
        so_dim.axis[arb_axis].var = args[1]

    # Set individual value axis sizes (not x-axis size)
    N_y.append(len(args[0]) - offset)

    # Calculate total 2D array size
    N_som = len(som)
    N_tot = N_som * N_y[-1]

    # Make second axis on total number of pixels
    so_dim.axis[pixel_axis].val = hlr_utils.make_axis(0, N_som, 1)
    if xvar:
        so_dim.axis[pixel_axis].var = nessi_list.NessiList(N_som+1)

    # Create y and var_y lists from total 2D size
    so_dim.y = nessi_list.NessiList(N_tot)
    so_dim.var_y = nessi_list.NessiList(N_tot)

    # Check for rebinning
    try:
        rebin = kwargs["rebin"]
    except KeyError:
        rebin = True

    # Rebin data to X axis
    if rebin:
        som_1 = common_lib.rebin_axis_1D(som, args[0])
    else:
        som_1 = som

    del som

    import array_manip
    
    for i in xrange(hlr_utils.get_length(som_1)):

        val = hlr_utils.get_value(som_1, i, "SOM", "y")
        err2 = hlr_utils.get_err2(som_1, i, "SOM", "y")

        start = i * N_y[0]

        (so_dim.y, so_dim.var_y) = array_manip.add_ncerr(so_dim.y,
                                                         so_dim.var_y,
                                                         val,
                                                         err2,
                                                         a_start=start)

        
    # Check for so_id keyword argument
    try:
        so_dim.id = kwargs["so_id"]
    except KeyError:
        so_dim.id = 0

    comb_som = SOM.SOM()
    comb_som.copyAttributes(som_1)

    del som_1

    # Check for y_label keyword argument
    try:
        comb_som.setYLabel(kwargs["y_label"])
    except KeyError:        
        comb_som.setYLabel("Counts")

    # Check for y_units keyword argument
    try:
        comb_som.setYUnits(kwargs["y_units"])
    except KeyError:
        comb_som.setYUnits("Counts / Arb")

    # Check for x_label keyword argument
    try:
        comb_som.setAllAxisLabels(["Pixel Number", kwargs["x_label"]])
    except KeyError:
        comb_som.setAllAxisLabels(["Pixel Number", "Arbitrary"])

    # Check for x_units keyword argument
    try:
        comb_som.setAllAxisUnits(["Pixel#", kwargs["x_units"]])
    except KeyError:
        comb_som.setAllAxisUnits(["Pixel#", "Arb"])

    comb_som.append(so_dim)

    del so_dim

    return comb_som
Пример #2
0
def sum_all_spectra(obj, **kwargs):
    """
    This function takes all the spectra in the given object and sums them
    together. All of the sprectra are assumed to have the same axis scale.
    
    @param obj: Object in which all of the spectra are to be summed together
    @type obj: C{SOM.SOM}
    
    @param kwargs: A list of keyword arguments that the function accepts:
    
    @keyword rebin_axis: The axis(es) to rebin the spectra onto.
    @type rebin_axis: C{nessi_list.NessiList} or C{list} of
                      C{nessi_list.NessiList}s
                      
    @keyword rebin_axis_dim: Tthe dimension on the spectra being rebinned.
                             The default value is I{1}.
    @type rebin_axis_dim: C{int}
    
    @keyword y_sort: A flag that will sort the spectrum IDs by y. The default
                     behavior is I{False} and this maintains the original x
                     ordering.
    @type y_sort: C{boolean}
    
    @keyword stripe: A flag that will combine spectra in either the x or y
                     direction at a given y or x. The integration direction is
                     based on the setting of y_sort. The default behavior is
                     I{False} and corresponds to summing all spectra into one.
    @type stripe: C{boolean}

    @keyword pix_fix: A single or list of pixel IDs with which to override the
                      summed spectrum pixel ID. The setting of y_sort
                      determines is the x component (y_sort=False) or the y
                      component (y_sort=True) of the pixel ID is overridden.
    @type pix_fix: C{int} or C{list} of C{int}s
    

    @return: Object containing a single spectrum
    @rtype: C{SOM.SOM}
    
    
    @raise TypeError: Anything other than a C{SOM} is given
    
    @raise RuntimeError: An unknown rebinning dimension is given
    """

    o_descr = hlr_utils.get_descr(obj)

    if o_descr != "SOM":
        raise TypeError("Function argument must be a SOM")
    # Have a SOM, go on
    else:
        pass

    # If there is only one SO, why run
    if len(obj) == 1:
        return obj
    # OK, we need to sum
    else:
        pass

    try:
        rebin_axis = kwargs["rebin_axis"]
    except KeyError:
        rebin_axis = None

    try:
        rebin_axis_dim = kwargs["rebin_axis_dim"]
    except KeyError:
        rebin_axis_dim = 1

    try:
        y_sort = kwargs["y_sort"]
    except KeyError:
        y_sort = False

    try:
        stripe = kwargs["stripe"]
    except KeyError:
        stripe = False

    try:
        pix_fix = kwargs["pixel_fix"]
    except KeyError:
        pix_fix = None

    import common_lib

    if rebin_axis is not None:
        if rebin_axis_dim == 1:
            obj1 = common_lib.rebin_axis_1D(obj, rebin_axis)
        elif rebin_axis_dim == 2:
            obj1 = common_lib.rebin_axis_2D(obj, rebin_axis[0], rebin_axis[1])
        else:
            raise RuntimeError("Do not have rebinning method for %dD." % \
                               rebin_axis_dim)
    else:
        obj1 = obj

    del obj

    # Sort SO IDs by y value
    if y_sort:
        obj1.sort(lambda x, y: cmp(x.id[1][1], y.id[1][1]))
    # SO IDs are already sorted by x value
    else:
        pass

    (result, res_descr) = hlr_utils.empty_result(obj1)

    result = hlr_utils.copy_som_attr(result, res_descr, obj1, o_descr)

    if not stripe:
        # iterate through the values
        so_id_list = []

        val1 = hlr_utils.get_value(obj1, 0, o_descr, "all")
        val2 = hlr_utils.get_value(obj1, 1, o_descr, "all")
        value = common_lib.add_ncerr(val1, val2)
        so_id_list.append(val1.id)
        so_id_list.append(val2.id)

        for i in xrange(2, hlr_utils.get_length(obj1)):
            val = hlr_utils.get_value(obj1, i, o_descr, "all")
            value = common_lib.add_ncerr(val, value)
            so_id_list.append(val.id)

        hlr_utils.result_insert(result, res_descr, value, None, "all")
        result.attr_list["Summed IDs"] = so_id_list

        if pix_fix is not None:
            if y_sort:
                fixed_pixel = (so_id_list[0][0], (pix_fix,
                                                  so_id_list[0][1][1]))
            else:
                fixed_pixel = (so_id_list[0][0], (so_id_list[0][1][0],
                                                  pix_fix))
        else:
            fixed_pixel = so_id_list[0]

        result[0].id = fixed_pixel

    else:
        # iterate through the values
        so_id_list = []
        i_start = 0
        stripe_count = 0
        total_size = hlr_utils.get_length(obj1)
        while i_start < total_size:
            stripe_list = []
            counted = 2
            val1 = hlr_utils.get_value(obj1, i_start, o_descr, "all")
            val2 = hlr_utils.get_value(obj1, i_start + 1, o_descr, "all")
            value = common_lib.add_ncerr(val1, val2)
            stripe_list.append(val1.id)
            stripe_list.append(val2.id)

            if y_sort:
                comp_id = val2.id[1][1]
            else:
                comp_id = val2.id[1][0]

            for i in xrange(i_start + 2, total_size):
                val = hlr_utils.get_value(obj1, i, o_descr, "all")
                if y_sort:
                    new_id = val.id[1][1]
                else:
                    new_id = val.id[1][0]

                if new_id > comp_id:
                    break

                value = common_lib.add_ncerr(val, value)
                stripe_list.append(val.id)
                counted += 1

            i_start += counted

            so_id_list.append(stripe_list)
            hlr_utils.result_insert(result, res_descr, value, None, "all")

            if pix_fix is not None:
                try:
                    if y_sort:
                        fixed_pixel = (stripe_list[0][0],
                                       (pix_fix[stripe_count],
                                        stripe_list[0][1][1]))
                    else:
                        fixed_pixel = (stripe_list[0][0],
                                       (stripe_list[0][1][0],
                                        pix_fix[stripe_count]))

                except TypeError:
                    if y_sort:
                        fixed_pixel = (stripe_list[0][0],
                                       (pix_fix, stripe_list[0][1][1]))
                    else:
                        fixed_pixel = (stripe_list[0][0],
                                       (stripe_list[0][1][0], pix_fix))
            else:
                fixed_pixel = stripe_list[0]

            result[stripe_count].id = fixed_pixel
            stripe_count += 1

        result.attr_list["summed_ids"] = so_id_list

    return result
Пример #3
0
def rebin_efficiency(obj1, obj2, **kwargs):
    """
    This function takes two objects and rebins the data for obj1 onto the axis
    provided by obj2. The units on the x-axes needs to be I{Angstroms}, since
    this is what the efficiencies will be present as.

    @param obj1: Object that will be rebinned
    @type obj1: C{SOM.SOM} or C{SOM.SO}
    
    @param obj2: Object that will provide the axis for rebinning
    @type obj2: C{SOM.SOM} or C{SOM.SO}
    
    @param kwargs: A list of keyword arguments that the function accepts:
    
    @keyword units: The expected units for this function. The default for this
                    function is I{Angstroms}.
    @type units: C{string}


    @return: Object that has been rebinned
    @rtype: C{SOM.SOM} or C{SOM.SO}


    @raise TypeError: The C{SOM}-C{SO} operation is attempted
    
    @raise TypeError: The C{SO}-C{SOM} operation is attempted
    
    @raise TypeError: obj1 not a C{SOM} or C{SO}
    
    @raise TypeError: obj2 not a C{SOM} or C{SO}
    
    @raise IndexError: The C{SOM}s do not have the same number of C{SO}s
    
    @raise RuntimeError: The C{SOM} x-axis units are not I{Angstroms}
    
    @raise RuntimeError: The x-axis units of the C{SOM}s do not match
    """

    # import the helper functions
    import hlr_utils

    # Kickout if monitor object is None
    if obj1 is None:
        return obj1

    # set up for working through data
    (result, res_descr) = hlr_utils.empty_result(obj1, obj2)
    (o1_descr, o2_descr) = hlr_utils.get_descr(obj1, obj2)

    # error checking for types
    if o1_descr == "SOM" and o2_descr == "SO":
        raise TypeError, "SOM-SO operation not supported"
    elif o1_descr == "SO" and o2_descr == "SOM":
        raise TypeError("SO-SOM operation not supported")
    # Have the right object combination, go on
    else:
        pass

    # Setup keyword arguments
    try:
        units = kwargs["units"]
    except KeyError:
        units = "Angstroms"

    if o1_descr == "SOM" and o2_descr == "SOM":
        hlr_utils.math_compatible(obj1, o1_descr, obj2, o2_descr)
    # If both objects are not SOMs, do nothing
    else:
        pass

    result = hlr_utils.copy_som_attr(result, res_descr, obj2, o2_descr)

    if res_descr == "SOM":
        result = hlr_utils.force_units(result, units)
    # Can't force units on anything other than a SOM
    else:
        pass

    # iterate through the values
    import common_lib

    for i in xrange(hlr_utils.get_length(obj1, obj2)):
        val1 = hlr_utils.get_value(obj1, i, o1_descr, "all")
        val2 = hlr_utils.get_value(obj2, i, o2_descr, "x")

        value = common_lib.rebin_axis_1D(val1, val2)

        hlr_utils.result_insert(result, res_descr, value, None, "all")

    return result
Пример #4
0
def sum_all_spectra(obj, **kwargs):
    """
    This function takes all the spectra in the given object and sums them
    together. All of the sprectra are assumed to have the same axis scale.
    
    @param obj: Object in which all of the spectra are to be summed together
    @type obj: C{SOM.SOM}
    
    @param kwargs: A list of keyword arguments that the function accepts:
    
    @keyword rebin_axis: The axis(es) to rebin the spectra onto.
    @type rebin_axis: C{nessi_list.NessiList} or C{list} of
                      C{nessi_list.NessiList}s
                      
    @keyword rebin_axis_dim: Tthe dimension on the spectra being rebinned.
                             The default value is I{1}.
    @type rebin_axis_dim: C{int}
    
    @keyword y_sort: A flag that will sort the spectrum IDs by y. The default
                     behavior is I{False} and this maintains the original x
                     ordering.
    @type y_sort: C{boolean}
    
    @keyword stripe: A flag that will combine spectra in either the x or y
                     direction at a given y or x. The integration direction is
                     based on the setting of y_sort. The default behavior is
                     I{False} and corresponds to summing all spectra into one.
    @type stripe: C{boolean}

    @keyword pix_fix: A single or list of pixel IDs with which to override the
                      summed spectrum pixel ID. The setting of y_sort
                      determines is the x component (y_sort=False) or the y
                      component (y_sort=True) of the pixel ID is overridden.
    @type pix_fix: C{int} or C{list} of C{int}s
    

    @return: Object containing a single spectrum
    @rtype: C{SOM.SOM}
    
    
    @raise TypeError: Anything other than a C{SOM} is given
    
    @raise RuntimeError: An unknown rebinning dimension is given
    """

    o_descr = hlr_utils.get_descr(obj)

    if o_descr != "SOM":
        raise TypeError("Function argument must be a SOM")
    # Have a SOM, go on
    else:
        pass

    # If there is only one SO, why run
    if len(obj) == 1:
        return obj
    # OK, we need to sum 
    else:
        pass

    try:
        rebin_axis = kwargs["rebin_axis"]
    except KeyError:
        rebin_axis = None

    try:
        rebin_axis_dim = kwargs["rebin_axis_dim"]
    except KeyError:
        rebin_axis_dim = 1

    try:
        y_sort = kwargs["y_sort"]
    except KeyError:
        y_sort = False

    try:
        stripe = kwargs["stripe"]
    except KeyError:
        stripe = False        

    try:
        pix_fix = kwargs["pixel_fix"]
    except KeyError:
        pix_fix = None

    import common_lib

    if rebin_axis is not None:
        if rebin_axis_dim == 1:
            obj1 = common_lib.rebin_axis_1D(obj, rebin_axis)
        elif rebin_axis_dim == 2:
            obj1 = common_lib.rebin_axis_2D(obj, rebin_axis[0], rebin_axis[1])
        else:
            raise RuntimeError("Do not have rebinning method for %dD." % \
                               rebin_axis_dim)
    else:
        obj1 = obj

    del obj

    # Sort SO IDs by y value
    if y_sort:
        obj1.sort(lambda x, y: cmp(x.id[1][1], y.id[1][1]))
    # SO IDs are already sorted by x value
    else:
        pass

    (result, res_descr) = hlr_utils.empty_result(obj1)

    result = hlr_utils.copy_som_attr(result, res_descr, obj1, o_descr)

    if not stripe:
        # iterate through the values
        so_id_list = []
        
        val1 = hlr_utils.get_value(obj1, 0, o_descr, "all")
        val2 = hlr_utils.get_value(obj1, 1, o_descr, "all")
        value = common_lib.add_ncerr(val1, val2)
        so_id_list.append(val1.id)
        so_id_list.append(val2.id)
        
        for i in xrange(2, hlr_utils.get_length(obj1)):
            val = hlr_utils.get_value(obj1, i, o_descr, "all")
            value = common_lib.add_ncerr(val, value)
            so_id_list.append(val.id)
            
        hlr_utils.result_insert(result, res_descr, value, None, "all")
        result.attr_list["Summed IDs"] = so_id_list

        if pix_fix is not None:
            if y_sort:
                fixed_pixel = (so_id_list[0][0], (pix_fix,
                                                  so_id_list[0][1][1]))
            else:
                fixed_pixel = (so_id_list[0][0], (so_id_list[0][1][0],
                                                  pix_fix))
        else:
            fixed_pixel = so_id_list[0]            
            
        result[0].id = fixed_pixel

    else:
        # iterate through the values        
        so_id_list = []
        i_start = 0
        stripe_count = 0
        total_size = hlr_utils.get_length(obj1)
        while i_start < total_size:
            stripe_list = []
            counted = 2
            val1 = hlr_utils.get_value(obj1, i_start, o_descr, "all")
            val2 = hlr_utils.get_value(obj1, i_start+1, o_descr, "all")
            value = common_lib.add_ncerr(val1, val2)
            stripe_list.append(val1.id)
            stripe_list.append(val2.id)

            if y_sort:
                comp_id = val2.id[1][1]
            else:
                comp_id = val2.id[1][0]
            
            for i in xrange(i_start+2, total_size):
                val = hlr_utils.get_value(obj1, i, o_descr, "all")
                if y_sort:
                    new_id = val.id[1][1]
                else:
                    new_id = val.id[1][0]

                if new_id > comp_id:
                    break
                
                value = common_lib.add_ncerr(val, value)
                stripe_list.append(val.id)
                counted += 1

            i_start += counted

            so_id_list.append(stripe_list)
            hlr_utils.result_insert(result, res_descr, value, None, "all")

            if pix_fix is not None:
                try:
                    if y_sort:
                        fixed_pixel = (stripe_list[0][0],
                                       (pix_fix[stripe_count],
                                        stripe_list[0][1][1]))
                    else:
                        fixed_pixel = (stripe_list[0][0],
                                       (stripe_list[0][1][0],
                                        pix_fix[stripe_count]))
                    
                except TypeError:
                    if y_sort:
                        fixed_pixel = (stripe_list[0][0],
                                       (pix_fix,
                                        stripe_list[0][1][1]))
                    else:
                        fixed_pixel = (stripe_list[0][0],
                                       (stripe_list[0][1][0],
                                        pix_fix))
            else:
                fixed_pixel = stripe_list[0]

            result[stripe_count].id = fixed_pixel
            stripe_count += 1

        result.attr_list["summed_ids"] = so_id_list            

    return result
Пример #5
0
def rebin_efficiency(obj1, obj2, **kwargs):
    """
    This function takes two objects and rebins the data for obj1 onto the axis
    provided by obj2. The units on the x-axes needs to be I{Angstroms}, since
    this is what the efficiencies will be present as.

    @param obj1: Object that will be rebinned
    @type obj1: C{SOM.SOM} or C{SOM.SO}
    
    @param obj2: Object that will provide the axis for rebinning
    @type obj2: C{SOM.SOM} or C{SOM.SO}
    
    @param kwargs: A list of keyword arguments that the function accepts:
    
    @keyword units: The expected units for this function. The default for this
                    function is I{Angstroms}.
    @type units: C{string}


    @return: Object that has been rebinned
    @rtype: C{SOM.SOM} or C{SOM.SO}


    @raise TypeError: The C{SOM}-C{SO} operation is attempted
    
    @raise TypeError: The C{SO}-C{SOM} operation is attempted
    
    @raise TypeError: obj1 not a C{SOM} or C{SO}
    
    @raise TypeError: obj2 not a C{SOM} or C{SO}
    
    @raise IndexError: The C{SOM}s do not have the same number of C{SO}s
    
    @raise RuntimeError: The C{SOM} x-axis units are not I{Angstroms}
    
    @raise RuntimeError: The x-axis units of the C{SOM}s do not match
    """

    # import the helper functions
    import hlr_utils

    # Kickout if monitor object is None
    if obj1 is None:
        return obj1
    
    # set up for working through data
    (result, res_descr) = hlr_utils.empty_result(obj1, obj2)
    (o1_descr, o2_descr) = hlr_utils.get_descr(obj1, obj2)
    
    # error checking for types
    if o1_descr == "SOM" and o2_descr == "SO":
        raise TypeError, "SOM-SO operation not supported"
    elif o1_descr == "SO" and o2_descr == "SOM":
        raise TypeError("SO-SOM operation not supported")
    # Have the right object combination, go on
    else:
        pass

    # Setup keyword arguments
    try:
        units = kwargs["units"]
    except KeyError:
        units = "Angstroms"
   
    if o1_descr == "SOM" and o2_descr == "SOM":
        hlr_utils.math_compatible(obj1, o1_descr, obj2, o2_descr)
    # If both objects are not SOMs, do nothing
    else:
        pass

    result = hlr_utils.copy_som_attr( result, res_descr, obj2, o2_descr)

    if res_descr == "SOM":
        result = hlr_utils.force_units(result, units)
    # Can't force units on anything other than a SOM
    else:
        pass

    # iterate through the values
    import common_lib

    for i in xrange(hlr_utils.get_length(obj1, obj2)):
        val1 = hlr_utils.get_value(obj1, i, o1_descr, "all")
        val2 = hlr_utils.get_value(obj2, i, o2_descr, "x")
        
        value = common_lib.rebin_axis_1D(val1, val2)
        
        hlr_utils.result_insert(result, res_descr, value, None, "all")

    return result
Пример #6
0
def create_X_vs_pixpos(som, *args, **kwargs):
    """
    This function takes a group of single spectrum with any given axes
    (wavelength, energy etc.) and rebins those axes to the given axis and
    converts the spectra into a single I{I(X, pixel)} spectrum.

    @param som: The input object with arbitrary (but same) axis spectra
    @type som: C{SOM.SOM}
    
    @param args: A mandatory list of axes for rebinning.  There is a particular
                 order to them. They should be present in the following order:
    
                 Without errors
                   1. Axis
                 With errors
                   1. Axis
                   2. Axis error^2
    @type args: C{nessi_list.NessiList}s
    
    @param kwargs: A list of keyword arguments that the function accepts:
    
    @keyword withXVar: A flag for whether the function should be expecting the
                       associated axes to have errors. The default value will
                       be I{False}.
    @type withXVar: C{boolean}

    @keyword data_type: The name of the data type which can be either
                        I{histogram}, I{density} or I{coordinate}. The default
                        value will be I{histogram}.
    @type data_type: C{string}
    
    @keyword so_id: The identifier represents a number, string, tuple or other
                    object that describes the resulting C{SO}.
    @type so_id: C{int}, C{string}, C{tuple}, C{pixel ID}
    
    @keyword y_label: The dependent axis label
    @type y_label: C{string}
    
    @keyword y_units: The dependent axis units
    @type y_units: C{string}
    
    @keyword x_label: The second primary axis label
    @type x_label: C{string}
    
    @keyword x_units: The second primary axis units
    @type x_units: C{string}

    @keyword rebin: A flag for turning rebin on or off. The default is I{True}.
    @type rebin: C{boolean}


    @return: Object with a single 2D C{SO} with the given axis and global pixel
             position
    @rtype: C{SOM.SOM}


    @raise RuntimeError: The parameter given to the keyword argument withXVar
                         is not I{True} or I{False}
                         
    @raise RuntimeError: The parameter given to the keyword argument data_type
                         is not I{histogram} or I{density} or I{coordinate}.
                         
    @raise RuntimeError: The number of given arguments (x-axes) is not either 2
                         (no errors) or 4 (with errors)
    """

    import common_lib
    import nessi_list

    # Setup some variables
    dim = 2
    N_y = []
    N_tot = 1
    N_args = len(args)

    # Check withXVar keyword argument and also check number of given args.
    # Set xvar to the appropriate value
    try:
        value = kwargs["withXVar"]
        if value.lower() == "true":
            if N_args != 2:
                raise RuntimeError("Since you have requested x errors, 2 x "\
                                   +"axes must be provided.")
            else:
                xvar = True
        elif value.lower() == "false":
            if N_args != 2:
                raise RuntimeError("Since you did not requested x errors, 2 "\
                                   +"x axes must be provided.")
            else:
                xvar = False
        else:
            raise RuntimeError("Do not understand given parameter %s" % \
                               value)
    except KeyError:
        if N_args != 1:
            raise RuntimeError("Since you did not requested x errors, 1 "\
                               +"x axes must be provided.")
        else:
            xvar = False

    # Check dataType keyword argument. An offset will be set to 1 for the
    # histogram type and 0 for either density or coordinate
    try:
        data_type = kwargs["data_type"]
        if data_type.lower() == "histogram":
            offset = 1
        elif data_type.lower() == "density" or \
                 data_type.lower() == "coordinate":
            offset = 0
        else:
            raise RuntimeError("Do not understand data type given: %s" % \
                               data_type)
    # Default is offset for histogram
    except KeyError:
        offset = 1

    so_dim = SOM.SO(dim)

    arb_axis = 1
    pixel_axis = 0

    # Set the x-axis arguments from the *args list into the new SO
    if not xvar:
        so_dim.axis[arb_axis].val = args[0]
    else:
        so_dim.axis[arb_axis].val = args[0]
        so_dim.axis[arb_axis].var = args[1]

    # Set individual value axis sizes (not x-axis size)
    N_y.append(len(args[0]) - offset)

    # Calculate total 2D array size
    N_som = len(som)
    N_tot = N_som * N_y[-1]

    # Make second axis on total number of pixels
    so_dim.axis[pixel_axis].val = hlr_utils.make_axis(0, N_som, 1)
    if xvar:
        so_dim.axis[pixel_axis].var = nessi_list.NessiList(N_som + 1)

    # Create y and var_y lists from total 2D size
    so_dim.y = nessi_list.NessiList(N_tot)
    so_dim.var_y = nessi_list.NessiList(N_tot)

    # Check for rebinning
    try:
        rebin = kwargs["rebin"]
    except KeyError:
        rebin = True

    # Rebin data to X axis
    if rebin:
        som_1 = common_lib.rebin_axis_1D(som, args[0])
    else:
        som_1 = som

    del som

    import array_manip

    for i in xrange(hlr_utils.get_length(som_1)):

        val = hlr_utils.get_value(som_1, i, "SOM", "y")
        err2 = hlr_utils.get_err2(som_1, i, "SOM", "y")

        start = i * N_y[0]

        (so_dim.y, so_dim.var_y) = array_manip.add_ncerr(so_dim.y,
                                                         so_dim.var_y,
                                                         val,
                                                         err2,
                                                         a_start=start)

    # Check for so_id keyword argument
    try:
        so_dim.id = kwargs["so_id"]
    except KeyError:
        so_dim.id = 0

    comb_som = SOM.SOM()
    comb_som.copyAttributes(som_1)

    del som_1

    # Check for y_label keyword argument
    try:
        comb_som.setYLabel(kwargs["y_label"])
    except KeyError:
        comb_som.setYLabel("Counts")

    # Check for y_units keyword argument
    try:
        comb_som.setYUnits(kwargs["y_units"])
    except KeyError:
        comb_som.setYUnits("Counts / Arb")

    # Check for x_label keyword argument
    try:
        comb_som.setAllAxisLabels(["Pixel Number", kwargs["x_label"]])
    except KeyError:
        comb_som.setAllAxisLabels(["Pixel Number", "Arbitrary"])

    # Check for x_units keyword argument
    try:
        comb_som.setAllAxisUnits(["Pixel#", kwargs["x_units"]])
    except KeyError:
        comb_som.setAllAxisUnits(["Pixel#", "Arb"])

    comb_som.append(so_dim)

    del so_dim

    return comb_som