def init_scatt_wavevector_to_scalar_Q(initk, scattk, **kwargs): """ This function takes an initial wavevector and a scattered wavevector as a C{tuple} and a C{SOM}, a C{tuple} and a C{SO} or two C{tuple}s and calculates the quantity scalar Q units of I{1/Angstroms}. The C{SOM} principle axis must be in units of I{1/Angstroms}. The C{SO}s and C{tuple}(s) is(are) assumed to be in units of I{1/Angstroms}. The polar angle must be provided if one of the initial arguments is not a C{SOM}. If a C{SOM} is passed, by providing the polar angle at the function call time, the polar angle carried in the C{SOM} instrument will be overridden. @param initk: Object holding the initial wavevector @type initk: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param scattk: Object holding the scattered wavevector @type scattk: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword polar: The polar angle and its associated error^2 @type polar: C{tuple} or C{list} of C{tuple}s @keyword units: The expected units for this function. The default for this function is I{1/Angstroms}. @type units: C{string} @return: Object converted to scalar Q @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The C{SOM}-C{SOM} operation is attempted @raise TypeError: The C{SOM}-C{SO} operation is attempted @raise TypeError: The C{SO}-C{SOM} operation is attempted @raise TypeError: The C{SO}-C{SO} operation is attempted @raise RuntimeError: The C{SOM} x-axis units are not I{1/Angstroms} @raise RuntimeError: A C{SOM} is not passed and no polar angle is provided @raise RuntimeError: No C{SOM.Instrument} is provided in a C{SOM} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(initk, scattk) (i_descr, s_descr) = hlr_utils.get_descr(initk, scattk) # error checking for types if i_descr == "SOM" and s_descr == "SOM": raise TypeError("SOM-SOM operation not supported") elif i_descr == "SOM" and s_descr == "SO": raise TypeError("SOM-SO operation not supported") elif i_descr == "SO" and s_descr == "SOM": raise TypeError("SO-SOM operation not supported") elif i_descr == "SO" and s_descr == "SO": raise TypeError("SO-SO operation not supported") else: pass # Setup keyword arguments try: polar = kwargs["polar"] except KeyError: polar = None try: units = kwargs["units"] except KeyError: units = "1/Angstroms" result = hlr_utils.copy_som_attr(result, res_descr, initk, i_descr, scattk, s_descr) if res_descr == "SOM": index = hlr_utils.one_d_units(result, units) result = hlr_utils.force_units(result, units, index) result.setAxisLabel(index, "scalar wavevector transfer") result.setYUnits("Counts/A-1") result.setYLabel("Intensity") else: pass if polar is None: if i_descr == "SOM": try: initk.attr_list.instrument.get_primary() inst = initk.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") elif s_descr == "SOM": try: scattk.attr_list.instrument.get_primary() inst = scattk.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: raise RuntimeError("If no SOM is provided, then polar "\ +"information must be given.") else: p_descr = hlr_utils.get_descr(polar) # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(initk, scattk)): val1 = hlr_utils.get_value(initk, i, i_descr, "x") err2_1 = hlr_utils.get_err2(initk, i, i_descr, "x") val2 = hlr_utils.get_value(scattk, i, s_descr, "x") err2_2 = hlr_utils.get_err2(scattk, i, s_descr, "x") map_so = hlr_utils.get_map_so(initk, scattk, i) if polar is None: (angle, angle_err2) = hlr_utils.get_parameter("polar", map_so, inst) else: angle = hlr_utils.get_value(polar, i, p_descr) angle_err2 = hlr_utils.get_err2(polar, i, p_descr) value = axis_manip.init_scatt_wavevector_to_scalar_Q(val1, err2_1, val2, err2_2, angle, angle_err2) hlr_utils.result_insert(result, res_descr, value, map_so, "x") return result
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
def tof_to_wavelength(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to wavelength. The wavelength axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(tof, tof_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(wavelength, wavelength_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword pathlength: The pathlength and its associated error^2 @type pathlength: C{tuple} or C{list} of C{tuple}s @keyword inst_param: The type of parameter requested from an associated instrument. For this function the acceptable parameters are I{primary}, I{secondary} and I{total}. Default is I{primary}. @type inst_param: C{string} @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is I{True} for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds}. @type units: C{string} @return: Object with a primary axis in time-of-flight converted to wavelength @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} @raise RuntimeError: A C{SOM} does not contain an instrument and no pathlength was provided @raise RuntimeError: No C{SOM} is provided and no pathlength given """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: inst_param = kwargs["inst_param"] except KeyError: inst_param = "primary" try: pathlength = kwargs["pathlength"] except KeyError: pathlength = None try: units = kwargs["units"] except KeyError: units = "microseconds" try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "Angstroms", axis) result.setAxisLabel(axis, "wavelength") result.setYUnits("Counts/A") result.setYLabel("Intensity") else: pass if pathlength is not None: p_descr = hlr_utils.get_descr(pathlength) else: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided") else: raise RuntimeError("If no SOM is provided, then pathlength "\ +"information must be provided") # iterate through the values import axis_manip if lojac: import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if pathlength is None: (pl, pl_err2) = hlr_utils.get_parameter(inst_param, map_so, inst) else: pl = hlr_utils.get_value(pathlength, i, p_descr) pl_err2 = hlr_utils.get_err2(pathlength, i, p_descr) value = axis_manip.tof_to_wavelength(val, err2, pl, pl_err2) if lojac: y_val = hlr_utils.get_value(obj, i, o_descr, "y") y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y") counts = utils.linear_order_jacobian(val, value[0], y_val, y_err2) hlr_utils.result_insert(result, res_descr, counts, map_so, "all", axis, [value[0]]) else: hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis) return result
def initial_wavelength_igs_lin_time_zero_to_tof(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from initial_wavelength_igs_lin_time_zero to time-of-flight. The initial_wavelength_igs_lin_time_zero axis for a C{SOM} must be in units of I{Angstroms}. The primary axis of a C{SO} is assumed to be in units of I{Angstroms}. A C{tuple} of C{(initial_wavelength_igs_lin_time_zero, initial_wavelength_igs_lin_time_zero_err2)} (assumed to be in units of I{Angstroms}) can be converted to C{(tof, tof_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword lambda_f:The final wavelength and its associated error^2 @type lambda_f: C{tuple} @keyword time_zero_slope: The time zero slope and its associated error^2 @type time_zero_slope: C{tuple} @keyword time_zero_offset: The time zero offset and its associated error^2 @type time_zero_offset: C{tuple} @keyword dist_source_sample: The source to sample distance information and its associated error^2 @type dist_source_sample: C{tuple} or C{list} of C{tuple}s @keyword dist_sample_detector: The sample to detector distance information and its associated error^2 @type dist_sample_detector: C{tuple} or C{list} of C{tuple}s @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is True for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{Angstroms} @type units: C{string} @return: Object with a primary axis in initial_wavelength_igs converted to time-of-flight @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{Angstroms} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: lambda_f = kwargs["lambda_f"] except KeyError: lambda_f = None try: time_zero_slope = kwargs["time_zero_slope"] except KeyError: time_zero_slope = None # Current constants for Time Zero Slope TIME_ZERO_SLOPE = (float(0.0), float(0.0)) try: time_zero_offset = kwargs["time_zero_offset"] except KeyError: time_zero_offset = None # Current constants for Time Zero Offset TIME_ZERO_OFFSET = (float(0.0), float(0.0)) try: dist_source_sample = kwargs["dist_source_sample"] except KeyError: dist_source_sample = None try: dist_sample_detector = kwargs["dist_sample_detector"] except KeyError: dist_sample_detector = None try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) try: units = kwargs["units"] except KeyError: units = "Angstroms" # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "Microseconds", axis) result.setAxisLabel(axis, "time-of-flight") result.setYUnits("Counts/uS") result.setYLabel("Intensity") else: pass # Where to get instrument information if dist_source_sample is None or dist_sample_detector is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: if dist_source_sample is None and dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample and sample-detector "\ +"distances must be provided.") elif dist_source_sample is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample distance must be provided.") elif dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"sample-detector distance must be "\ +"provided.") else: raise RuntimeError("If you get here, see Steve Miller for "\ +"your mug.") else: pass if lambda_f is not None: l_descr = hlr_utils.get_descr(lambda_f) else: if o_descr == "SOM": try: som_l_f = obj.attr_list["Wavelength_final"] except KeyError: raise RuntimeError("Please provide a final wavelength "\ +"parameter either via the function call "\ +"or the SOM") else: raise RuntimeError("You need to provide a final wavelength") if time_zero_slope is not None: t_0_slope_descr = hlr_utils.get_descr(time_zero_slope) else: if o_descr == "SOM": try: t_0_slope = obj.attr_list["Time_zero_slope"][0] t_0_slope_err2 = obj.attr_list["Time_zero_slope"][1] except KeyError: t_0_slope = TIME_ZERO_SLOPE[0] t_0_slope_err2 = TIME_ZERO_SLOPE[1] else: t_0_slope = TIME_ZERO_SLOPE[0] t_0_slope_err2 = TIME_ZERO_SLOPE[1] if time_zero_offset is not None: t_0_offset_descr = hlr_utils.get_descr(time_zero_offset) else: if o_descr == "SOM": try: t_0_offset = obj.attr_list["Time_zero_offset"][0] t_0_offset_err2 = obj.attr_list["Time_zero_offset"][1] except KeyError: t_0_offset = TIME_ZERO_OFFSET[0] t_0_offset_err2 = TIME_ZERO_OFFSET[1] else: t_0_offset = TIME_ZERO_OFFSET[0] t_0_offset_err2 = TIME_ZERO_OFFSET[1] if dist_source_sample is not None: ls_descr = hlr_utils.get_descr(dist_source_sample) # Do nothing, go on else: pass if dist_sample_detector is not None: ld_descr = hlr_utils.get_descr(dist_sample_detector) # Do nothing, go on else: pass # iterate through the values len_obj = hlr_utils.get_length(obj) MNEUT_OVER_H = 1.0 / 0.003956034 MNEUT_OVER_H2 = MNEUT_OVER_H * MNEUT_OVER_H for i in xrange(len_obj): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if dist_source_sample is None: (L_s, L_s_err2) = hlr_utils.get_parameter("primary", map_so, inst) else: L_s = hlr_utils.get_value(dist_source_sample, i, ls_descr) L_s_err2 = hlr_utils.get_err2(dist_source_sample, i, ls_descr) if dist_sample_detector is None: (L_d, L_d_err2) = hlr_utils.get_parameter("secondary", map_so, inst) else: L_d = hlr_utils.get_value(dist_sample_detector, i, ld_descr) L_d_err2 = hlr_utils.get_err2(dist_sample_detector, i, ld_descr) if lambda_f is not None: l_f = hlr_utils.get_value(lambda_f, i, l_descr) l_f_err2 = hlr_utils.get_err2(lambda_f, i, l_descr) else: l_f_tuple = hlr_utils.get_special(som_l_f, map_so) l_f = l_f_tuple[0] l_f_err2 = l_f_tuple[1] if time_zero_slope is not None: t_0_slope = hlr_utils.get_value(time_zero_slope, i, t_0_slope_descr) t_0_slope_err2 = hlr_utils.get_err2(time_zero_slope, i, t_0_slope_descr) else: pass if time_zero_offset is not None: t_0_offset = hlr_utils.get_value(time_zero_offset, i, t_0_offset_descr) t_0_offset_err2 = hlr_utils.get_err2(time_zero_offset, i, t_0_offset_descr) else: pass # Going to violate rules since the current usage is with a single # number. When an SCL equivalent function arises, this code can be # fixed. front_const = MNEUT_OVER_H * L_s + t_0_slope term2 = MNEUT_OVER_H * l_f * L_d tof = (front_const * val) + term2 + t_0_offset front_const2 = front_const * front_const eterm1 = l_f * l_f * L_d_err2 eterm2 = L_d * L_d * l_f_err2 eterm3 = MNEUT_OVER_H2 * L_s_err2 tof_err2 = (front_const2 * err2) + (val * val) * \ (eterm3 + t_0_slope_err2) + (MNEUT_OVER_H2 * \ (eterm1 + eterm2)) + \ t_0_offset_err2 hlr_utils.result_insert(result, res_descr, (tof, tof_err2), None, "all") return result
def tof_to_ref_scalar_Q(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to reflectometer scalar Q. This means that a single angle and a single flightpath is used. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(time-of-flight, time-of-flight_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(scalar_Q, scalar_Q_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword polar: The polar angle and its associated error^2 @type polar: C{tuple} @keyword pathlength: The pathlength and its associated error^2 @type pathlength: C{tuple} @keyword angle_offset: A constant offset for the polar angle and its associated error^2. The units of the offset should be in radians. @type angle_offset: C{tuple} @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is True for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds}. @type units: C{string} @keyword configure: This is the object containing the driver configuration. This will signal the function to write out the counts and fractional area to files. @type configure: C{Configure} @return: Object with a primary axis in time-of-flight converted to reflectometer scalar Q @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: A C{SOM} is not passed and no polar angle is provided @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "list": raise TypeError("Do not know how to handle given type: %s" % \ o_descr) else: pass # Setup keyword arguments polar = kwargs.get("polar") pathlength = kwargs.get("pathlength") units = kwargs.get("units", "microseconds") lojac = kwargs.get("lojac", hlr_utils.check_lojac(obj)) angle_offset = kwargs.get("angle_offset") config = kwargs.get("configure") if config is None: beamdiv_corr = False else: beamdiv_corr = config.beamdiv_corr # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "1/Angstroms", axis) result.setAxisLabel(axis, "scalar wavevector transfer") result.setYUnits("Counts/A-1") result.setYLabel("Intensity") else: pass if pathlength is None or polar is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided") else: if pathlength is None and polar is None: raise RuntimeError("If no SOM is provided, then pathlength "\ +"and polar angle information must be "\ +"provided") elif pathlength is None: raise RuntimeError("If no SOM is provided, then pathlength "\ +"information must be provided") elif polar is None: raise RuntimeError("If no SOM is provided, then polar angle "\ +"information must be provided") else: raise RuntimeError("If you get here, see Steve Miller for "\ +"your mug.") else: pass if pathlength is None: (pl, pl_err2) = obj.attr_list.instrument.get_total_path(obj[0].id, det_secondary=True) else: (pl, pl_err2) = pathlength if polar is None: angle = hlr_utils.get_special(obj.attr_list["data-theta"], obj[0])[0] angle_err2 = 0.0 else: (angle, angle_err2) = polar if angle_offset is not None: angle += angle_offset[0] angle_err2 += angle_offset[1] # Need to multiply angle by 2.0 in order to make it be Theta to # underlying conversion function angle *= 2.0 angle_err2 *= 4.0 # iterate through the values import axis_manip if lojac: import utils if beamdiv_corr: import dr_lib for i in xrange(hlr_utils.get_length(obj)): skip_pixel = False val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if beamdiv_corr: dangle = dr_lib.ref_beamdiv_correct(obj.attr_list, map_so.id, config.det_spat_res, config.center_pix) # We subtract due to the inversion of the z coordinates from the # mirror reflection of the beam at the sample. if dangle is not None: pangle = angle - (2.0 * dangle) else: pangle = angle skip_pixel = True else: pangle = angle value = axis_manip.tof_to_scalar_Q(val, err2, pl, pl_err2, pangle, angle_err2) if lojac: y_val = hlr_utils.get_value(obj, i, o_descr, "y") y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y") counts = utils.linear_order_jacobian(val, value[0], y_val, y_err2) else: pass if o_descr != "number": value1 = axis_manip.reverse_array_cp(value[0]) value2 = axis_manip.reverse_array_cp(value[1]) rev_value = (value1, value2) else: rev_value = value if map_so is not None: if not lojac: map_so.y = axis_manip.reverse_array_cp(map_so.y) map_so.var_y = axis_manip.reverse_array_cp(map_so.var_y) else: map_so.y = axis_manip.reverse_array_cp(counts[0]) map_so.var_y = axis_manip.reverse_array_cp(counts[1]) else: pass if not skip_pixel: hlr_utils.result_insert(result, res_descr, rev_value, map_so, "x", axis) return result
def tof_to_wavelength_lin_time_zero(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to wavelength incorporating a linear time zero which is a described as a linear function of the wavelength. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(tof, tof_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(wavelength, wavelength_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword pathlength: The pathlength and its associated error^2 @type pathlength: C{tuple} or C{list} of C{tuple}s @keyword time_zero_slope: The time zero slope and its associated error^2 @type time_zero_slope: C{tuple} @keyword time_zero_offset: The time zero offset and its associated error^2 @type time_zero_offset: C{tuple} @keyword inst_param: The type of parameter requested from an associated instrument. For this function the acceptable parameters are I{primary}, I{secondary} and I{total}. Default is I{primary}. @type inst_param: C{string} @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is I{True} for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds}. @type units: C{string} @keyword cut_val: Specify a wavelength to cut the spectra at. @type cut_val: C{float} @keyword cut_less: A flag that specifies cutting the spectra less than C{cut_val}. The default is C{True}. @type cut_less: C{boolean} @return: Object with a primary axis in time-of-flight converted to wavelength @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} @raise RuntimeError: A C{SOM} does not contain an instrument and no pathlength was provided @raise RuntimeError: No C{SOM} is provided and no pathlength given """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: inst_param = kwargs["inst_param"] except KeyError: inst_param = "primary" try: pathlength = kwargs["pathlength"] except KeyError: pathlength = None try: time_zero_slope = kwargs["time_zero_slope"] except KeyError: time_zero_slope = None # Current constants for Time Zero Slope TIME_ZERO_SLOPE = (float(0.0), float(0.0)) try: time_zero_offset = kwargs["time_zero_offset"] except KeyError: time_zero_offset = None # Current constants for Time Zero Offset TIME_ZERO_OFFSET = (float(0.0), float(0.0)) try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) try: units = kwargs["units"] except KeyError: units = "microseconds" try: cut_val = kwargs["cut_val"] except KeyError: cut_val = None try: cut_less = kwargs["cut_less"] except KeyError: cut_less = True # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "Angstroms", axis) result.setAxisLabel(axis, "wavelength") result.setYUnits("Counts/A") result.setYLabel("Intensity") else: pass if pathlength is not None: p_descr = hlr_utils.get_descr(pathlength) else: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided") else: raise RuntimeError("If no SOM is provided, then pathlength "\ +"information must be provided") if time_zero_slope is not None: t_0_slope_descr = hlr_utils.get_descr(time_zero_slope) else: if o_descr == "SOM": try: t_0_slope = obj.attr_list["Time_zero_slope"][0] t_0_slope_err2 = obj.attr_list["Time_zero_slope"][1] except KeyError: t_0_slope = TIME_ZERO_SLOPE[0] t_0_slope_err2 = TIME_ZERO_SLOPE[1] else: t_0_slope = TIME_ZERO_SLOPE[0] t_0_slope_err2 = TIME_ZERO_SLOPE[1] if time_zero_offset is not None: t_0_offset_descr = hlr_utils.get_descr(time_zero_offset) else: if o_descr == "SOM": try: t_0_offset = obj.attr_list["Time_zero_offset"][0] t_0_offset_err2 = obj.attr_list["Time_zero_offset"][1] except KeyError: t_0_offset = TIME_ZERO_OFFSET[0] t_0_offset_err2 = TIME_ZERO_OFFSET[1] else: t_0_offset = TIME_ZERO_OFFSET[0] t_0_offset_err2 = TIME_ZERO_OFFSET[1] # iterate through the values import axis_manip if lojac or cut_val is not None: import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if pathlength is None: (pl, pl_err2) = hlr_utils.get_parameter(inst_param, map_so, inst) else: pl = hlr_utils.get_value(pathlength, i, p_descr) pl_err2 = hlr_utils.get_err2(pathlength, i, p_descr) if time_zero_slope is not None: t_0_slope = hlr_utils.get_value(time_zero_slope, i, t_0_slope_descr) t_0_slope_err2 = hlr_utils.get_err2(time_zero_slope, i, t_0_slope_descr) else: pass if time_zero_offset is not None: t_0_offset = hlr_utils.get_value(time_zero_offset, i, t_0_offset_descr) t_0_offset_err2 = hlr_utils.get_err2(time_zero_offset, i, t_0_offset_descr) else: pass value = axis_manip.tof_to_wavelength_lin_time_zero(val, err2, pl, pl_err2, t_0_slope, t_0_slope_err2, t_0_offset, t_0_offset_err2) if cut_val is not None: index = utils.bisect_helper(value[0], cut_val) if cut_less: # Need to cut at this index, so increment by one index += 1 value[0].__delslice__(0, index) value[1].__delslice__(0, index) map_so.y.__delslice__(0, index) map_so.var_y.__delslice__(0, index) if lojac: val.__delslice__(0, index) err2.__delslice__(0, index) else: len_data = len(value[0]) # All axis arrays need starting index adjusted by one since # they always carry one more bin than the data value[0].__delslice__(index + 1, len_data) value[1].__delslice__(index + 1, len_data) map_so.y.__delslice__(index, len_data) map_so.var_y.__delslice__(index, len_data) if lojac: val.__delslice__(index + 1, len_data) err2.__delslice__(index + 1, len_data) if lojac: counts = utils.linear_order_jacobian(val, value[0], map_so.y, map_so.var_y) hlr_utils.result_insert(result, res_descr, counts, map_so, "all", axis, [value[0]]) else: hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis) return result
def wavelength_to_d_spacing(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from wavelength to d-spacing. The wavelength axis for a C{SOM} must be in units of I{Angstroms}. The primary axis of a C{SO} is assumed to be in units of I{Angstroms}. A C{tuple} of C{(wavelength, wavelength_err2)} (assumed to be in units of I{Angstroms}) can be converted to C{(d_spacing, d_spacing_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword polar:The polar angle and its associated error^2 @type polar: C{tuple} @keyword units: The expected units for this function. The default for this function is I{Angstroms} @type units: C{string} @return: Object with a primary axis in wavelength converted to d-spacing @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: A C{SOM} is not passed and no polar angle is provided @raise RuntimeError: The C{SOM} x-axis units are not I{Angstroms} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "list": raise TypeError("Do not know how to handle given type: %s" % \ o_descr) else: pass # Setup keyword arguments try: polar = kwargs["polar"] except KeyError: polar = None try: units = kwargs["units"] except KeyError: units = "Angstroms" # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "Angstroms", axis) result.setAxisLabel(axis, "d-spacing") result.setYUnits("Counts/A") result.setYLabel("Intensity") else: pass if polar is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: raise RuntimeError("If no SOM is provided, then polar "\ +"information must be given.") else: p_descr = hlr_utils.get_descr(polar) # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if polar is None: (angle, angle_err2) = hlr_utils.get_parameter("polar", map_so, inst) else: angle = hlr_utils.get_value(polar, i, p_descr) angle_err2 = hlr_utils.get_err2(polar, i, p_descr) value = axis_manip.wavelength_to_d_spacing(val, err2, angle, angle_err2) hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis) return result
def wavelength_to_scalar_k(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from wavelength to scalar k. The wavelength axis for a C{SOM} must be in units of I{Angstroms}. The primary axis of a C{SO} is assumed to be in units of I{Angstroms}. A C{tuple} of C{(wavelength, wavelength_err2)} (assumed to be in units of I{Angstroms}) can be converted to C{(scalar_k, scalar_k_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @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 with a primary axis in wavelength converted to scalar k @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{Angstroms} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "list": raise TypeError("Do not know how to handle given type: %s" % \ o_descr) else: pass # Setup keyword arguments try: units = kwargs["units"] except KeyError: units = "Angstroms" # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "1/Angstroms", axis) result.setAxisLabel(axis, "scalar wavevector") result.setYUnits("Counts/A-1") result.setYLabel("Intensity") else: pass # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) value = axis_manip.wavelength_to_scalar_k(val, err2) if o_descr != "number": value1 = axis_manip.reverse_array_cp(value[0]) value2 = axis_manip.reverse_array_cp(value[1]) rev_value = (value1, value2) else: rev_value = value map_so = hlr_utils.get_map_so(obj, None, i) if map_so is not None: map_so.y = axis_manip.reverse_array_cp(map_so.y) map_so.var_y = axis_manip.reverse_array_cp(map_so.var_y) else: pass hlr_utils.result_insert(result, res_descr, rev_value, map_so, "x", axis) return result
def frequency_to_energy(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from frequency to energy. The frequency axis for a C{SOM} must be in units of I{THz}. The primary axis of a C{SO} is assumed to be in units of I{THz}. A C{tuple} of C{(frequency, frequency_err2)} (assumed to be in units of I{THz}) can be converted to C{(energy, energy_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @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{THz}. @type units: C{string} @return: Object with primary axis in frequency converted to energy @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{THz} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: units = kwargs["units"] except KeyError: units = "THz" # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if o_descr == "SOM": result = hlr_utils.force_units(result, "meV", axis) result.setAxisLabel(axis, "energy transfer") result.setYUnits("Counts/meV") result.setYLabel("Intensity") else: pass # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) value = axis_manip.frequency_to_energy(val, err2) map_so = hlr_utils.get_map_so(obj, None, i) hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis) return result
def tof_to_final_velocity_dgs(obj, velocity_i, time_zero_offset, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to final_velocity_dgs. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(tof, tof_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(final_velocity_dgs, final_velocity_dgs_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param velocity_i: The initial velocity and its associated error^2 @type velocity_i: C{tuple} @param time_zero_offset: The time zero offset and its associated error^2 @type time_zero_offset: C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword dist_source_sample: The source to sample distance information and its associated error^2 @type dist_source_sample: C{tuple} or C{list} of C{tuple}s @keyword dist_sample_detector: The sample to detector distance information and its associated error^2 @type dist_sample_detector: C{tuple} or C{list} of C{tuple}s @keyword run_filter: This determines if the filter on the negative velocities is run. The default setting is True. @type run_filter: C{boolean} @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is True for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds} @type units: C{string} @return: Object with a primary axis in time-of-flight converted to final_velocity_dgs @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} """ import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: dist_source_sample = kwargs["dist_source_sample"] except KeyError: dist_source_sample = None try: dist_sample_detector = kwargs["dist_sample_detector"] except KeyError: dist_sample_detector = None try: units = kwargs["units"] except KeyError: units = "microseconds" try: run_filter = kwargs["run_filter"] except KeyError: run_filter = True try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "meters/microseconds", axis) result.setAxisLabel(axis, "velocity") result.setYUnits("Counts/meters/microseconds") result.setYLabel("Intensity") else: pass # Where to get instrument information if dist_source_sample is None or dist_sample_detector is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: if dist_source_sample is None and dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample and sample-detector "\ +"distances must be provided.") elif dist_source_sample is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample distance must be provided.") elif dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"sample-detector distance must be "\ +"provided.") else: raise RuntimeError("If you get here, see Steve Miller for "\ +"your mug.") else: pass if dist_source_sample is not None: ls_descr = hlr_utils.get_descr(dist_source_sample) # Do nothing, go on else: pass if dist_sample_detector is not None: ld_descr = hlr_utils.get_descr(dist_sample_detector) # Do nothing, go on else: pass # iterate through the values import axis_manip if lojac: import utils len_obj = hlr_utils.get_length(obj) for i in xrange(len_obj): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if dist_source_sample is None: (L_s, L_s_err2) = hlr_utils.get_parameter("primary", map_so, inst) else: L_s = hlr_utils.get_value(dist_source_sample, i, ls_descr) L_s_err2 = hlr_utils.get_err2(dist_source_sample, i, ls_descr) if dist_sample_detector is None: (L_d, L_d_err2) = hlr_utils.get_parameter("secondary", map_so, inst) else: L_d = hlr_utils.get_value(dist_sample_detector, i, ld_descr) L_d_err2 = hlr_utils.get_err2(dist_sample_detector, i, ld_descr) value = axis_manip.tof_to_final_velocity_dgs(val, err2, velocity_i[0], velocity_i[1], time_zero_offset[0], time_zero_offset[1], L_s, L_s_err2, L_d, L_d_err2) # Remove all velocities < 0 if run_filter: index = 0 for valx in value[0]: if valx >= 0: break index += 1 value[0].__delslice__(0, index) value[1].__delslice__(0, index) map_so.y.__delslice__(0, index) map_so.var_y.__delslice__(0, index) if lojac: val.__delslice__(0, index) err2.__delslice__(0, index) else: pass if lojac: (map_so.y, map_so.var_y) = utils.linear_order_jacobian( val, value[0], map_so.y, map_so.var_y) # Need to reverse arrays due to conversion if o_descr != "number": valx = axis_manip.reverse_array_cp(value[0]) valxe = axis_manip.reverse_array_cp(value[1]) rev_value = (valx, valxe) else: rev_value = value if map_so is not None: map_so.y = axis_manip.reverse_array_cp(map_so.y) map_so.var_y = axis_manip.reverse_array_cp(map_so.var_y) hlr_utils.result_insert(result, res_descr, rev_value, map_so, "x", axis) return result
def tof_to_final_velocity_dgs(obj, velocity_i, time_zero_offset, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to final_velocity_dgs. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(tof, tof_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(final_velocity_dgs, final_velocity_dgs_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param velocity_i: The initial velocity and its associated error^2 @type velocity_i: C{tuple} @param time_zero_offset: The time zero offset and its associated error^2 @type time_zero_offset: C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword dist_source_sample: The source to sample distance information and its associated error^2 @type dist_source_sample: C{tuple} or C{list} of C{tuple}s @keyword dist_sample_detector: The sample to detector distance information and its associated error^2 @type dist_sample_detector: C{tuple} or C{list} of C{tuple}s @keyword run_filter: This determines if the filter on the negative velocities is run. The default setting is True. @type run_filter: C{boolean} @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is True for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds} @type units: C{string} @return: Object with a primary axis in time-of-flight converted to final_velocity_dgs @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} """ import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: dist_source_sample = kwargs["dist_source_sample"] except KeyError: dist_source_sample = None try: dist_sample_detector = kwargs["dist_sample_detector"] except KeyError: dist_sample_detector = None try: units = kwargs["units"] except KeyError: units = "microseconds" try: run_filter = kwargs["run_filter"] except KeyError: run_filter = True try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "meters/microseconds", axis) result.setAxisLabel(axis, "velocity") result.setYUnits("Counts/meters/microseconds") result.setYLabel("Intensity") else: pass # Where to get instrument information if dist_source_sample is None or dist_sample_detector is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: if dist_source_sample is None and dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample and sample-detector "\ +"distances must be provided.") elif dist_source_sample is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample distance must be provided.") elif dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"sample-detector distance must be "\ +"provided.") else: raise RuntimeError("If you get here, see Steve Miller for "\ +"your mug.") else: pass if dist_source_sample is not None: ls_descr = hlr_utils.get_descr(dist_source_sample) # Do nothing, go on else: pass if dist_sample_detector is not None: ld_descr = hlr_utils.get_descr(dist_sample_detector) # Do nothing, go on else: pass # iterate through the values import axis_manip if lojac: import utils len_obj = hlr_utils.get_length(obj) for i in xrange(len_obj): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if dist_source_sample is None: (L_s, L_s_err2) = hlr_utils.get_parameter("primary", map_so, inst) else: L_s = hlr_utils.get_value(dist_source_sample, i, ls_descr) L_s_err2 = hlr_utils.get_err2(dist_source_sample, i, ls_descr) if dist_sample_detector is None: (L_d, L_d_err2) = hlr_utils.get_parameter("secondary", map_so, inst) else: L_d = hlr_utils.get_value(dist_sample_detector, i, ld_descr) L_d_err2 = hlr_utils.get_err2(dist_sample_detector, i, ld_descr) value = axis_manip.tof_to_final_velocity_dgs(val, err2, velocity_i[0], velocity_i[1], time_zero_offset[0], time_zero_offset[1], L_s, L_s_err2, L_d, L_d_err2) # Remove all velocities < 0 if run_filter: index = 0 for valx in value[0]: if valx >= 0: break index += 1 value[0].__delslice__(0, index) value[1].__delslice__(0, index) map_so.y.__delslice__(0, index) map_so.var_y.__delslice__(0, index) if lojac: val.__delslice__(0, index) err2.__delslice__(0, index) else: pass if lojac: (map_so.y, map_so.var_y) = utils.linear_order_jacobian(val, value[0], map_so.y, map_so.var_y) # Need to reverse arrays due to conversion if o_descr != "number": valx = axis_manip.reverse_array_cp(value[0]) valxe = axis_manip.reverse_array_cp(value[1]) rev_value = (valx, valxe) else: rev_value = value if map_so is not None: map_so.y = axis_manip.reverse_array_cp(map_so.y) map_so.var_y = axis_manip.reverse_array_cp(map_so.var_y) hlr_utils.result_insert(result, res_descr, rev_value, map_so, "x", axis) return result
def tof_to_initial_wavelength_igs(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to initial_wavelength_igs. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(tof, tof_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(initial_wavelength_igs, initial_wavelength_igs_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword lambda_f:The final wavelength and its associated error^2 @type lambda_f: C{tuple} @keyword time_zero: The time zero offset and its associated error^2 @type time_zero: C{tuple} @keyword dist_source_sample: The source to sample distance information and its associated error^2 @type dist_source_sample: C{tuple} or C{list} of C{tuple}s @keyword dist_sample_detector: The sample to detector distance information and its associated error^2 @type dist_sample_detector: C{tuple} or C{list} of C{tuple}s @keyword run_filter: This determines if the filter on the negative wavelengths is run. The default setting is True. @type run_filter: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds} @type units: C{string} @return: Object with a primary axis in time-of-flight converted to initial_wavelength_igs @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: lambda_f = kwargs["lambda_f"] except KeyError: lambda_f = None try: time_zero = kwargs["time_zero"] except KeyError: time_zero = None try: dist_source_sample = kwargs["dist_source_sample"] except KeyError: dist_source_sample = None try: dist_sample_detector = kwargs["dist_sample_detector"] except KeyError: dist_sample_detector = None try: units = kwargs["units"] except KeyError: units = "microseconds" try: run_filter = kwargs["run_filter"] except KeyError: run_filter = True # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "Angstroms", axis) result.setAxisLabel(axis, "wavelength") result.setYUnits("Counts/A") result.setYLabel("Intensity") else: pass # Where to get instrument information if dist_source_sample is None or dist_sample_detector is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: if dist_source_sample is None and dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample and sample-detector "\ +"distances must be provided.") elif dist_source_sample is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample distance must be provided.") elif dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"sample-detector distance must be "\ +"provided.") else: raise RuntimeError("If you get here, see Steve Miller for "\ +"your mug.") else: pass if lambda_f is not None: l_descr = hlr_utils.get_descr(lambda_f) else: if o_descr == "SOM": try: som_l_f = obj.attr_list["Wavelength_final"] except KeyError: raise RuntimeError("Please provide a final wavelength "\ +"parameter either via the function call "\ +"or the SOM") else: raise RuntimeError("You need to provide a final wavelength") if time_zero is not None: t_descr = hlr_utils.get_descr(time_zero) else: if o_descr == "SOM": try: t_0 = obj.attr_list["Time_zero"][0] t_0_err2 = obj.attr_list["Time_zero"][1] except KeyError: raise RuntimeError("Please provide a time-zero "\ +"parameter either via the function call "\ +"or the SOM") else: t_0 = 0.0 t_0_err2 = 0.0 if dist_source_sample is not None: ls_descr = hlr_utils.get_descr(dist_source_sample) # Do nothing, go on else: pass if dist_sample_detector is not None: ld_descr = hlr_utils.get_descr(dist_sample_detector) # Do nothing, go on else: pass # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if dist_source_sample is None: (L_s, L_s_err2) = hlr_utils.get_parameter("primary", map_so, inst) else: L_s = hlr_utils.get_value(dist_source_sample, i, ls_descr) L_s_err2 = hlr_utils.get_err2(dist_source_sample, i, ls_descr) if dist_sample_detector is None: (L_d, L_d_err2) = hlr_utils.get_parameter("secondary", map_so, inst) else: L_d = hlr_utils.get_value(dist_sample_detector, i, ld_descr) L_d_err2 = hlr_utils.get_err2(dist_sample_detector, i, ld_descr) if lambda_f is not None: l_f = hlr_utils.get_value(lambda_f, i, l_descr) l_f_err2 = hlr_utils.get_err2(lambda_f, i, l_descr) else: l_f_tuple = hlr_utils.get_special(som_l_f, map_so) l_f = l_f_tuple[0] l_f_err2 = l_f_tuple[1] if time_zero is not None: t_0 = hlr_utils.get_value(time_zero, i, t_descr) t_0_err2 = hlr_utils.get_err2(time_zero, i, t_descr) else: pass value = axis_manip.tof_to_initial_wavelength_igs(val, err2, l_f, l_f_err2, t_0, t_0_err2, L_s, L_s_err2, L_d, L_d_err2) # Remove all wavelengths < 0 if run_filter: index = 0 for val in value[0]: if val >= 0: break index += 1 value[0].__delslice__(0, index) value[1].__delslice__(0, index) map_so.y.__delslice__(0, index) map_so.var_y.__delslice__(0, index) else: pass hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis) return result
def tof_to_initial_wavelength_igs_lin_time_zero(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to initial_wavelength_igs_lin_time_zero. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(tof, tof_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(initial_wavelength_igs, initial_wavelength_igs_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword lambda_f:The final wavelength and its associated error^2 @type lambda_f: C{tuple} @keyword time_zero_slope: The time zero slope and its associated error^2 @type time_zero_slope: C{tuple} @keyword time_zero_offset: The time zero offset and its associated error^2 @type time_zero_offset: C{tuple} @keyword dist_source_sample: The source to sample distance information and its associated error^2 @type dist_source_sample: C{tuple} or C{list} of C{tuple}s @keyword dist_sample_detector: The sample to detector distance information and its associated error^2 @type dist_sample_detector: C{tuple} or C{list} of C{tuple}s @keyword run_filter: This determines if the filter on the negative wavelengths is run. The default setting is True. @type run_filter: C{boolean} @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is True for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds} @type units: C{string} @return: Object with a primary axis in time-of-flight converted to initial_wavelength_igs @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: lambda_f = kwargs["lambda_f"] except KeyError: lambda_f = None try: time_zero_slope = kwargs["time_zero_slope"] except KeyError: time_zero_slope = None # Current constants for Time Zero Slope TIME_ZERO_SLOPE = (float(0.0), float(0.0)) try: time_zero_offset = kwargs["time_zero_offset"] except KeyError: time_zero_offset = None # Current constants for Time Zero Offset TIME_ZERO_OFFSET = (float(0.0), float(0.0)) try: dist_source_sample = kwargs["dist_source_sample"] except KeyError: dist_source_sample = None try: dist_sample_detector = kwargs["dist_sample_detector"] except KeyError: dist_sample_detector = None try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) try: units = kwargs["units"] except KeyError: units = "microseconds" try: run_filter = kwargs["run_filter"] except KeyError: run_filter = True try: iobj = kwargs["iobj"] except KeyError: iobj = None # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "Angstroms", axis) result.setAxisLabel(axis, "wavelength") result.setYUnits("Counts/A") result.setYLabel("Intensity") else: pass # Where to get instrument information if dist_source_sample is None or dist_sample_detector is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument mobj = obj except RuntimeError: raise RuntimeError("A detector was not provided!") else: if iobj is None: if dist_source_sample is None and dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample and sample-detector "\ +"distances must be provided.") elif dist_source_sample is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample distance must be "\ +"provided.") elif dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"sample-detector distance must be "\ +"provided.") else: raise RuntimeError("If you get here, see Steve Miller "\ +"for your mug.") else: inst = iobj.attr_list.instrument mobj = iobj else: mobj = obj if lambda_f is not None: l_descr = hlr_utils.get_descr(lambda_f) else: if o_descr == "SOM": try: som_l_f = obj.attr_list["Wavelength_final"] except KeyError: raise RuntimeError("Please provide a final wavelength "\ +"parameter either via the function call "\ +"or the SOM") else: if iobj is None: raise RuntimeError("You need to provide a final wavelength") else: som_l_f = iobj.attr_list["Wavelength_final"] if time_zero_slope is not None: t_0_slope_descr = hlr_utils.get_descr(time_zero_slope) else: if o_descr == "SOM": try: t_0_slope = obj.attr_list["Time_zero_slope"][0] t_0_slope_err2 = obj.attr_list["Time_zero_slope"][1] except KeyError: t_0_slope = TIME_ZERO_SLOPE[0] t_0_slope_err2 = TIME_ZERO_SLOPE[1] else: t_0_slope = TIME_ZERO_SLOPE[0] t_0_slope_err2 = TIME_ZERO_SLOPE[1] if time_zero_offset is not None: t_0_offset_descr = hlr_utils.get_descr(time_zero_offset) else: if o_descr == "SOM": try: t_0_offset = obj.attr_list["Time_zero_offset"][0] t_0_offset_err2 = obj.attr_list["Time_zero_offset"][1] except KeyError: t_0_offset = TIME_ZERO_OFFSET[0] t_0_offset_err2 = TIME_ZERO_OFFSET[1] else: t_0_offset = TIME_ZERO_OFFSET[0] t_0_offset_err2 = TIME_ZERO_OFFSET[1] if dist_source_sample is not None: ls_descr = hlr_utils.get_descr(dist_source_sample) # Do nothing, go on else: pass if dist_sample_detector is not None: ld_descr = hlr_utils.get_descr(dist_sample_detector) # Do nothing, go on else: pass # iterate through the values import axis_manip if lojac: import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(mobj, None, i) if dist_source_sample is None: (L_s, L_s_err2) = hlr_utils.get_parameter("primary", map_so, inst) else: L_s = hlr_utils.get_value(dist_source_sample, i, ls_descr) L_s_err2 = hlr_utils.get_err2(dist_source_sample, i, ls_descr) if dist_sample_detector is None: (L_d, L_d_err2) = hlr_utils.get_parameter("secondary", map_so, inst) else: L_d = hlr_utils.get_value(dist_sample_detector, i, ld_descr) L_d_err2 = hlr_utils.get_err2(dist_sample_detector, i, ld_descr) if lambda_f is not None: l_f = hlr_utils.get_value(lambda_f, i, l_descr) l_f_err2 = hlr_utils.get_err2(lambda_f, i, l_descr) else: l_f_tuple = hlr_utils.get_special(som_l_f, map_so) l_f = l_f_tuple[0] l_f_err2 = l_f_tuple[1] if time_zero_slope is not None: t_0_slope = hlr_utils.get_value(time_zero_slope, i, t_0_slope_descr) t_0_slope_err2 = hlr_utils.get_err2(time_zero_slope, i, t_0_slope_descr) else: pass if time_zero_offset is not None: t_0_offset = hlr_utils.get_value(time_zero_offset, i, t_0_offset_descr) t_0_offset_err2 = hlr_utils.get_err2(time_zero_offset, i, t_0_offset_descr) else: pass value = axis_manip.tof_to_initial_wavelength_igs_lin_time_zero( val, err2, l_f, l_f_err2, t_0_slope, t_0_slope_err2, t_0_offset, t_0_offset_err2, L_s, L_s_err2, L_d, L_d_err2) # Remove all wavelengths < 0 if run_filter: index = 0 for valx in value[0]: if valx >= 0: break index += 1 value[0].__delslice__(0, index) value[1].__delslice__(0, index) map_so.y.__delslice__(0, index) map_so.var_y.__delslice__(0, index) if lojac: val.__delslice__(0, index) err2.__delslice__(0, index) else: pass if lojac: try: counts = utils.linear_order_jacobian(val, value[0], map_so.y, map_so.var_y) except Exception, e: # Lets us know offending pixel ID raise Exception(str(map_so.id) + " " + str(e)) hlr_utils.result_insert(result, res_descr, counts, map_so, "all", axis, [value[0]]) else: hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis)
def tof_to_scalar_Q(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to scalarQ. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(time-of-flight, time-of-flight_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(scalar_Q, scalar_Q_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword polar: The polar angle and its associated error^2 @type polar: C{tuple} or C{list} of C{tuple}s @keyword pathlength: The pathlength and its associated error^2 @type pathlength: C{tuple} or C{list} of C{tuple}s @keyword angle_offset: A constant offset for the polar angle and its associated error^2. The units of the offset should be in radians. @type angle_offset: C{tuple} @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is True for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds}. @type units: C{string} @return: Object with a primary axis in time-of-flight converted to scalar Q @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: A C{SOM} is not passed and no polar angle is provided @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "list": raise TypeError("Do not know how to handle given type: %s" % \ o_descr) else: pass # Setup keyword arguments try: polar = kwargs["polar"] except KeyError: polar = None try: pathlength = kwargs["pathlength"] except KeyError: pathlength = None try: units = kwargs["units"] except KeyError: units = "microseconds" try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) try: angle_offset = kwargs["angle_offset"] except KeyError: angle_offset = None # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "1/Angstroms", axis) result.setAxisLabel(axis, "scalar wavevector transfer") result.setYUnits("Counts/A-1") result.setYLabel("Intensity") else: pass if pathlength is None or polar is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided") else: if pathlength is None and polar is None: raise RuntimeError("If no SOM is provided, then pathlength "\ +"and polar angle information must be "\ +"provided") elif pathlength is None: raise RuntimeError("If no SOM is provided, then pathlength "\ +"information must be provided") elif polar is None: raise RuntimeError("If no SOM is provided, then polar angle "\ +"information must be provided") else: raise RuntimeError("If you get here, see Steve Miller for "\ +"your mug.") else: pass if pathlength is not None: p_descr = hlr_utils.get_descr(pathlength) else: pass if polar is not None: a_descr = hlr_utils.get_descr(polar) else: pass # iterate through the values import axis_manip if lojac: import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if pathlength is None: (pl, pl_err2) = hlr_utils.get_parameter("total", map_so, inst) else: pl = hlr_utils.get_value(pathlength, i, p_descr) pl_err2 = hlr_utils.get_err2(pathlength, i, p_descr) if polar is None: (angle, angle_err2) = hlr_utils.get_parameter("polar", map_so, inst) else: angle = hlr_utils.get_value(polar, i, a_descr) angle_err2 = hlr_utils.get_err2(polar, i, a_descr) if angle_offset is not None: angle += angle_offset[0] angle_err2 += angle_offset[1] value = axis_manip.tof_to_scalar_Q(val, err2, pl, pl_err2, angle, angle_err2) if lojac: y_val = hlr_utils.get_value(obj, i, o_descr, "y") y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y") counts = utils.linear_order_jacobian(val, value[0], y_val, y_err2) else: pass if o_descr != "number": value1 = axis_manip.reverse_array_cp(value[0]) value2 = axis_manip.reverse_array_cp(value[1]) rev_value = (value1, value2) else: rev_value = value if map_so is not None: if not lojac: map_so.y = axis_manip.reverse_array_cp(map_so.y) map_so.var_y = axis_manip.reverse_array_cp(map_so.var_y) else: map_so.y = axis_manip.reverse_array_cp(counts[0]) map_so.var_y = axis_manip.reverse_array_cp(counts[1]) else: pass hlr_utils.result_insert(result, res_descr, rev_value, map_so, "x", axis) return result
def igs_energy_transfer(obj, **kwargs): """ @depricated: This function will eventually disappear when the full S(Q,E) transformation for IGS detectors is completed and verified. This function takes a SOM or a SO and calculates the energy transfer for the IGS class of instruments. It is different from common_lib.energy_transfer in that the final wavelength is provided in a SOM.Information, SOM.CompositeInformation or a tuple, then converted to energy in place before being given to the common_lib.energy_transfer function. Parameters: ---------- -> obj -> kwargs is a list of key word arguments that the function accepts: units= a string containing the expected units for this function. The default for this function is meV lambda_f= a SOM.Information, SOM.CompositeInformation or a tuple containing the final wavelength information offset= a SOM.Information or SOM.CompositeInformation containing the final energy offsets scale=<boolean> is a flag that determines if the energy transfer results are scaled by the ratio of lambda_f/lambda_i. The default is False Returns: ------- <- A SOM or SO with the energy transfer calculated in units of THz Exceptions: ---------- <- RuntimeError is raised if the x-axis units are not meV <- RuntimeError is raised if a SOM or SO is not given to the function <- RuntimeError is raised if the final wavelength is not provided to the function """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "number" or o_descr == "list": raise RuntimeError, "Must provide a SOM of a SO to the function." # Go on else: pass # Setup keyword arguments try: units = kwargs["units"] except KeyError: units = "meV" try: lambda_f = kwargs["lambda_f"] except KeyError: lambda_f = None try: offset = kwargs["offset"] except KeyError: offset = None try: scale = kwargs["scale"] except KeyError: scale = False # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 if lambda_f is None: if o_descr == "SOM": try: lambda_f = obj.attr_list["Wavelength_final"] except KeyError: raise RuntimeError("Must provide a final wavelength via the "\ +"incoming SOM or the lambda_f keyword") else: raise RuntimeError("Must provide a final wavelength via the "\ +"lambda_f keyword") else: pass result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "ueV", axis) result.setAxisLabel(axis, "energy_transfer") result.setYUnits("Counts/ueV") result.setYLabel("Intensity") else: pass # iterate through the values import array_manip import axis_manip import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) y_val = hlr_utils.get_value(obj, i, o_descr, "y", axis) y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y", axis) map_so = hlr_utils.get_map_so(obj, None, i) l_f = hlr_utils.get_special(lambda_f, map_so) (E_f, E_f_err2) = axis_manip.wavelength_to_energy(l_f[0], l_f[1]) if offset is not None: info = hlr_utils.get_special(offset, map_so) try: E_f_new = array_manip.add_ncerr(E_f, E_f_err2, info[0], info[1]) except TypeError: # Have to do this since add_ncerr does not support # scalar-scalar operations value1 = E_f + info[0] value2 = E_f_err2 + info[1] E_f_new = (value1, value2) else: E_f_new = (E_f, E_f_err2) # Scale counts by lambda_f / lambda_i if scale: l_i = axis_manip.energy_to_wavelength(val, err2) l_i_bc = utils.calc_bin_centers(l_i[0], l_i[1]) ratio = array_manip.div_ncerr(l_f[0], l_f[1], l_i_bc[0], l_i_bc[1]) scale_y = array_manip.mult_ncerr(y_val, y_err2, ratio[0], ratio[1]) else: scale_y = (y_val, y_err2) value = array_manip.sub_ncerr(val, err2, E_f_new[0], E_f_new[1]) # Convert from meV to ueV value2 = array_manip.mult_ncerr(value[0], value[1], 1000.0, 0.0) value3 = array_manip.mult_ncerr(scale_y[0], scale_y[1], 1.0 / 1000.0, 0.0) hlr_utils.result_insert(result, res_descr, value3, map_so, "all", 0, [value2[0]]) return result
def energy_transfer(obj, itype, axis_const, **kwargs): """ This function takes a SOM with a wavelength axis (initial for IGS and final for DGS) and calculates the energy transfer. @param obj: The object containing the wavelength axis @type obj: C{SOM.SOM} @param itype: The instrument class type. The choices are either I{IGS} or I{DGS}. @type itype: C{string} @param axis_const: The attribute name for the axis constant which is the final wavelength for I{IGS} and the initial energy for I{DGS}. @type axis_const: C{string} @param kwargs: A list of keyword arguments that the function accepts: @keyword units: The units for the incoming axis. The default is I{Angstroms}. @type units: C{string} @keyword change_units: A flag that signals the function to convert from I{meV} to I{ueV}. The default is I{False}. @type change_units: C{boolean} @keyword scale: A flag to scale the y-axis by lambda_f/lambda_i for I{IGS} and lambda_i/lambda_f for I{DGS}. The default is I{False}. @type scale: C{boolean} @keyword lojac: A flag that turns on the calculation and application of the linear-order Jacobian. The default is I{False}. @type lojac: C{boolean} @keyword sa_norm: A flag to turn on solid angle normlaization. @type sa_norm: C{boolean} @return: Object with the energy transfer calculated in units of I{meV} or I{ueV}. The default is I{meV}. @rtype: C{SOM.SOM} @raise RuntimeError: The instrument class type is not recognized @raise RuntimeError: The x-axis units are not Angstroms @raise RuntimeError: A SOM is not given to the function """ # Check the instrument class type to make sure its allowed allowed_types = ["DGS", "IGS"] if itype not in allowed_types: raise RuntimeError("The instrument class type %s is not known. "\ +"Please use DGS or IGS" % itype) # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr != "SOM": raise RuntimeError("Must provide a SOM to the function.") # Go on else: pass # Setup keyword arguments try: units = kwargs["units"] except KeyError: units = "Angstroms" try: change_units = kwargs["change_units"] except KeyError: change_units = False try: scale = kwargs["scale"] except KeyError: scale = False try: sa_norm = kwargs["sa_norm"] except KeyError: sa_norm = False if sa_norm: inst = obj.attr_list.instrument try: lojac = kwargs["lojac"] except KeyError: lojac = False # Primary axis for transformation. axis = hlr_utils.one_d_units(obj, units) # Get the subtraction constant try: axis_c = obj.attr_list[axis_const] except KeyError: raise RuntimeError("Must provide a final wavelength (IGS) or initial "\ +"energy (DGS) via the incoming SOM") result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if change_units: unit_str = "ueV" else: unit_str = "meV" result = hlr_utils.force_units(result, unit_str, axis) result.setAxisLabel(axis, "energy_transfer") result.setYUnits("Counts/" + unit_str) result.setYLabel("Intensity") # iterate through the values import array_manip import axis_manip import dr_lib import utils for i in xrange(hlr_utils.get_length(obj)): if itype == "IGS": l_i = hlr_utils.get_value(obj, i, o_descr, "x", axis) l_i_err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) else: l_f = hlr_utils.get_value(obj, i, o_descr, "x", axis) l_f_err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) y_val = hlr_utils.get_value(obj, i, o_descr, "y", axis) y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y", axis) map_so = hlr_utils.get_map_so(obj, None, i) if itype == "IGS": (E_i, E_i_err2) = axis_manip.wavelength_to_energy(l_i, l_i_err2) l_f = hlr_utils.get_special(axis_c, map_so)[:2] (E_f, E_f_err2) = axis_manip.wavelength_to_energy(l_f[0], l_f[1]) if lojac: (y_val, y_err2) = utils.linear_order_jacobian(l_i, E_i, y_val, y_err2) else: (E_i, E_i_err2) = axis_c.toValErrTuple() (E_f, E_f_err2) = axis_manip.wavelength_to_energy(l_f, l_f_err2) if lojac: (y_val, y_err2) = utils.linear_order_jacobian(l_f, E_f, y_val, y_err2) if scale: # Scale counts by lambda_f / lambda_i if itype == "IGS": (l_n, l_n_err2) = l_f (l_d, l_d_err2) = utils.calc_bin_centers(l_i, l_i_err2) else: (l_n, l_n_err2) = utils.calc_bin_centers(l_f, l_f_err2) (l_d, l_d_err2) = axis_manip.energy_to_wavelength(E_i, E_i_err2) ratio = array_manip.div_ncerr(l_n, l_n_err2, l_d, l_d_err2) scale_y = array_manip.mult_ncerr(y_val, y_err2, ratio[0], ratio[1]) else: scale_y = (y_val, y_err2) value = array_manip.sub_ncerr(E_i, E_i_err2, E_f, E_f_err2) if change_units: # Convert from meV to ueV value2 = array_manip.mult_ncerr(value[0], value[1], 1000.0, 0.0) scale_y = array_manip.mult_ncerr(scale_y[0], scale_y[1], 1.0/1000.0, 0.0) else: value2 = value if sa_norm: if inst.get_name() == "BSS": dOmega = dr_lib.calc_BSS_solid_angle(map_so, inst) scale_y = array_manip.div_ncerr(scale_y[0], scale_y[1], dOmega, 0.0) else: raise RuntimeError("Do not know how to get solid angle from "\ +"%s" % inst.get_name()) if itype == "IGS": # Reverse the values due to the conversion value_y = axis_manip.reverse_array_cp(scale_y[0]) value_var_y = axis_manip.reverse_array_cp(scale_y[1]) value_x = axis_manip.reverse_array_cp(value2[0]) else: value_y = scale_y[0] value_var_y = scale_y[1] value_x = value2[0] hlr_utils.result_insert(result, res_descr, (value_y, value_var_y), map_so, "all", 0, [value_x]) return result
def energy_transfer(left, right, **kwargs): """ This function takes a C{tuple} and a C{SOM}, a C{tuple} and a C{SO} or two C{tuple}s and calculates the energy transfer in units of I{THz}. The C{SOM} principle axis must be in units of I{meV}. The C{SO} and C{tuple}s are assumed to be in units of I{meV}. @param left: Object on the left side of the subtraction @type left: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param right: Object on the right side of the subtraction @type right: C{SOM.SOM}, C{SOM.SO} or C{tuple} @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{meV} @type units: C{string} @return: Object based on left - right in units of I{THz} @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise RuntimeError: The x-axis units are not I{meV} @raise TypeError: C{SOM}-C{SOM} operation not supported @raise TypeError: C{SOM}-C{SO} operation not supported @raise TypeError: C{SO}-C{SOM} operation not supported @raise TypeError: C{SO}-C{SO} operation not supported """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(left, right) (l_descr, r_descr) = hlr_utils.get_descr(left, right) # error checking for types if l_descr == "SOM" and r_descr == "SOM": raise TypeError("SOM-SOM operation not supported") elif l_descr == "SOM" and r_descr == "SO": raise TypeError("SOM-SO operation not supported") elif l_descr == "SO" and r_descr == "SOM": raise TypeError("SO-SOM operation not supported") elif l_descr == "SO" and r_descr == "SO": raise TypeError("SO-SO operation not supported") else: pass # Setup keyword arguments try: units = kwargs["units"] except KeyError: units = "meV" result = hlr_utils.copy_som_attr(result, res_descr, left, l_descr, right, r_descr) if res_descr == "SOM": index = hlr_utils.one_d_units(result, units) result = hlr_utils.force_units(result, "THz", index) result.setAxisLabel(index, "energy transfer") result.setYUnits("Counts/THz") result.setYLabel("Intensity") else: pass # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(left, right)): val1 = hlr_utils.get_value(left, i, l_descr, "x") err2_1 = hlr_utils.get_err2(left, i, l_descr, "x") val2 = hlr_utils.get_value(right, i, r_descr, "x") err2_2 = hlr_utils.get_err2(right, i, r_descr, "x") value = axis_manip.energy_transfer(val1, err2_1, val2, err2_2) map_so = hlr_utils.get_map_so(left, right, i) hlr_utils.result_insert(result, res_descr, value, map_so, "x") return result
def wavelength_to_scalar_Q(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from wavelength to scalar Q. The wavelength axis for a C{SOM} must be in units of I{Angstroms}. The primary axis of a C{SO} is assumed to be in units of I{Angstroms}. A C{tuple} of C{(wavelength, wavelength_err2)} (assumed to be in units of I{Angstroms}) can be converted to C{(scalar_Q, scalar_Q_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword polar: The polar angle and its associated error^2 @type polar: C{tuple} or C{list} of C{tuple}s @keyword pathlength: The pathlength and its associated error^2 @type pathlength: C{tuple} or C{list} of C{tuple}s @keyword units: The expected units for this function. The default for this function is I{Angstroms}. @type units: C{string} @return: Object with a primary axis in wavelength converted to scalar Q @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: A C{SOM} is not passed and no polar angle is provided @raise RuntimeError: The C{SOM} x-axis units are not I{Angstroms} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "list": raise TypeError("Do not know how to handle given type: %s" % \ o_descr) else: pass # Setup keyword arguments try: polar = kwargs["polar"] except KeyError: polar = None try: units = kwargs["units"] except KeyError: units = "Angstroms" try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "1/Angstroms", axis) result.setAxisLabel(axis, "scalar wavevector transfer") result.setYUnits("Counts/A-1") result.setYLabel("Intensity") else: pass if polar is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: raise RuntimeError("If no SOM is provided, then polar "\ +"information must be given.") else: p_descr = hlr_utils.get_descr(polar) # iterate through the values import axis_manip if lojac: import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if polar is None: (angle, angle_err2) = hlr_utils.get_parameter("polar", map_so, inst) else: angle = hlr_utils.get_value(polar, i, p_descr) angle_err2 = hlr_utils.get_err2(polar, i, p_descr) value = axis_manip.wavelength_to_scalar_Q(val, err2, angle, angle_err2) if lojac: y_val = hlr_utils.get_value(obj, i, o_descr, "y") y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y") counts = utils.linear_order_jacobian(val, value[0], y_val, y_err2) else: pass if o_descr != "number": value1 = axis_manip.reverse_array_cp(value[0]) value2 = axis_manip.reverse_array_cp(value[1]) rev_value = (value1, value2) else: rev_value = value if map_so is not None: if not lojac: map_so.y = axis_manip.reverse_array_cp(map_so.y) map_so.var_y = axis_manip.reverse_array_cp(map_so.var_y) else: map_so.y = axis_manip.reverse_array_cp(counts[0]) map_so.var_y = axis_manip.reverse_array_cp(counts[1]) else: pass hlr_utils.result_insert(result, res_descr, rev_value, map_so, "x", axis) return result
def tof_to_initial_wavelength_igs(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to initial_wavelength_igs. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(tof, tof_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(initial_wavelength_igs, initial_wavelength_igs_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword lambda_f:The final wavelength and its associated error^2 @type lambda_f: C{tuple} @keyword time_zero: The time zero offset and its associated error^2 @type time_zero: C{tuple} @keyword dist_source_sample: The source to sample distance information and its associated error^2 @type dist_source_sample: C{tuple} or C{list} of C{tuple}s @keyword dist_sample_detector: The sample to detector distance information and its associated error^2 @type dist_sample_detector: C{tuple} or C{list} of C{tuple}s @keyword run_filter: This determines if the filter on the negative wavelengths is run. The default setting is True. @type run_filter: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds} @type units: C{string} @return: Object with a primary axis in time-of-flight converted to initial_wavelength_igs @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: lambda_f = kwargs["lambda_f"] except KeyError: lambda_f = None try: time_zero = kwargs["time_zero"] except KeyError: time_zero = None try: dist_source_sample = kwargs["dist_source_sample"] except KeyError: dist_source_sample = None try: dist_sample_detector = kwargs["dist_sample_detector"] except KeyError: dist_sample_detector = None try: units = kwargs["units"] except KeyError: units = "microseconds" try: run_filter = kwargs["run_filter"] except KeyError: run_filter = True # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "Angstroms", axis) result.setAxisLabel(axis, "wavelength") result.setYUnits("Counts/A") result.setYLabel("Intensity") else: pass # Where to get instrument information if dist_source_sample is None or dist_sample_detector is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: if dist_source_sample is None and dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample and sample-detector "\ +"distances must be provided.") elif dist_source_sample is None: raise RuntimeError("If a SOM is not passed, the "\ +"source-sample distance must be provided.") elif dist_sample_detector is None: raise RuntimeError("If a SOM is not passed, the "\ +"sample-detector distance must be "\ +"provided.") else: raise RuntimeError("If you get here, see Steve Miller for "\ +"your mug.") else: pass if lambda_f is not None: l_descr = hlr_utils.get_descr(lambda_f) else: if o_descr == "SOM": try: som_l_f = obj.attr_list["Wavelength_final"] except KeyError: raise RuntimeError("Please provide a final wavelength "\ +"parameter either via the function call "\ +"or the SOM") else: raise RuntimeError("You need to provide a final wavelength") if time_zero is not None: t_descr = hlr_utils.get_descr(time_zero) else: if o_descr == "SOM": try: t_0 = obj.attr_list["Time_zero"][0] t_0_err2 = obj.attr_list["Time_zero"][1] except KeyError: raise RuntimeError("Please provide a time-zero "\ +"parameter either via the function call "\ +"or the SOM") else: t_0 = 0.0 t_0_err2 = 0.0 if dist_source_sample is not None: ls_descr = hlr_utils.get_descr(dist_source_sample) # Do nothing, go on else: pass if dist_sample_detector is not None: ld_descr = hlr_utils.get_descr(dist_sample_detector) # Do nothing, go on else: pass # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if dist_source_sample is None: (L_s, L_s_err2) = hlr_utils.get_parameter("primary", map_so, inst) else: L_s = hlr_utils.get_value(dist_source_sample, i, ls_descr) L_s_err2 = hlr_utils.get_err2(dist_source_sample, i, ls_descr) if dist_sample_detector is None: (L_d, L_d_err2) = hlr_utils.get_parameter("secondary", map_so, inst) else: L_d = hlr_utils.get_value(dist_sample_detector, i, ld_descr) L_d_err2 = hlr_utils.get_err2(dist_sample_detector, i, ld_descr) if lambda_f is not None: l_f = hlr_utils.get_value(lambda_f, i, l_descr) l_f_err2 = hlr_utils.get_err2(lambda_f, i, l_descr) else: l_f_tuple = hlr_utils.get_special(som_l_f, map_so) l_f = l_f_tuple[0] l_f_err2 = l_f_tuple[1] if time_zero is not None: t_0 = hlr_utils.get_value(time_zero, i, t_descr) t_0_err2 = hlr_utils.get_err2(time_zero, i, t_descr) else: pass value = axis_manip.tof_to_initial_wavelength_igs( val, err2, l_f, l_f_err2, t_0, t_0_err2, L_s, L_s_err2, L_d, L_d_err2) # Remove all wavelengths < 0 if run_filter: index = 0 for val in value[0]: if val >= 0: break index += 1 value[0].__delslice__(0, index) value[1].__delslice__(0, index) map_so.y.__delslice__(0, index) map_so.var_y.__delslice__(0, index) else: pass hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis) return result
def igs_energy_transfer(obj, **kwargs): """ @depricated: This function will eventually disappear when the full S(Q,E) transformation for IGS detectors is completed and verified. This function takes a SOM or a SO and calculates the energy transfer for the IGS class of instruments. It is different from common_lib.energy_transfer in that the final wavelength is provided in a SOM.Information, SOM.CompositeInformation or a tuple, then converted to energy in place before being given to the common_lib.energy_transfer function. Parameters: ---------- -> obj -> kwargs is a list of key word arguments that the function accepts: units= a string containing the expected units for this function. The default for this function is meV lambda_f= a SOM.Information, SOM.CompositeInformation or a tuple containing the final wavelength information offset= a SOM.Information or SOM.CompositeInformation containing the final energy offsets scale=<boolean> is a flag that determines if the energy transfer results are scaled by the ratio of lambda_f/lambda_i. The default is False Returns: ------- <- A SOM or SO with the energy transfer calculated in units of THz Exceptions: ---------- <- RuntimeError is raised if the x-axis units are not meV <- RuntimeError is raised if a SOM or SO is not given to the function <- RuntimeError is raised if the final wavelength is not provided to the function """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "number" or o_descr == "list": raise RuntimeError, "Must provide a SOM of a SO to the function." # Go on else: pass # Setup keyword arguments try: units = kwargs["units"] except KeyError: units = "meV" try: lambda_f = kwargs["lambda_f"] except KeyError: lambda_f = None try: offset = kwargs["offset"] except KeyError: offset = None try: scale = kwargs["scale"] except KeyError: scale = False # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 if lambda_f is None: if o_descr == "SOM": try: lambda_f = obj.attr_list["Wavelength_final"] except KeyError: raise RuntimeError("Must provide a final wavelength via the "\ +"incoming SOM or the lambda_f keyword") else: raise RuntimeError("Must provide a final wavelength via the "\ +"lambda_f keyword") else: pass result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "ueV", axis) result.setAxisLabel(axis, "energy_transfer") result.setYUnits("Counts/ueV") result.setYLabel("Intensity") else: pass # iterate through the values import array_manip import axis_manip import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) y_val = hlr_utils.get_value(obj, i, o_descr, "y", axis) y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y", axis) map_so = hlr_utils.get_map_so(obj, None, i) l_f = hlr_utils.get_special(lambda_f, map_so) (E_f, E_f_err2) = axis_manip.wavelength_to_energy(l_f[0], l_f[1]) if offset is not None: info = hlr_utils.get_special(offset, map_so) try: E_f_new = array_manip.add_ncerr(E_f, E_f_err2, info[0], info[1]) except TypeError: # Have to do this since add_ncerr does not support # scalar-scalar operations value1 = E_f + info[0] value2 = E_f_err2 + info[1] E_f_new = (value1, value2) else: E_f_new = (E_f, E_f_err2) # Scale counts by lambda_f / lambda_i if scale: l_i = axis_manip.energy_to_wavelength(val, err2) l_i_bc = utils.calc_bin_centers(l_i[0], l_i[1]) ratio = array_manip.div_ncerr(l_f[0], l_f[1], l_i_bc[0], l_i_bc[1]) scale_y = array_manip.mult_ncerr(y_val, y_err2, ratio[0], ratio[1]) else: scale_y = (y_val, y_err2) value = array_manip.sub_ncerr(val, err2, E_f_new[0], E_f_new[1]) # Convert from meV to ueV value2 = array_manip.mult_ncerr(value[0], value[1], 1000.0, 0.0) value3 = array_manip.mult_ncerr(scale_y[0], scale_y[1], 1.0/1000.0, 0.0) hlr_utils.result_insert(result, res_descr, value3, map_so, "all", 0, [value2[0]]) return result
def init_scatt_wavevector_to_scalar_Q(initk, scattk, **kwargs): """ This function takes an initial wavevector and a scattered wavevector as a C{tuple} and a C{SOM}, a C{tuple} and a C{SO} or two C{tuple}s and calculates the quantity scalar Q units of I{1/Angstroms}. The C{SOM} principle axis must be in units of I{1/Angstroms}. The C{SO}s and C{tuple}(s) is(are) assumed to be in units of I{1/Angstroms}. The polar angle must be provided if one of the initial arguments is not a C{SOM}. If a C{SOM} is passed, by providing the polar angle at the function call time, the polar angle carried in the C{SOM} instrument will be overridden. @param initk: Object holding the initial wavevector @type initk: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param scattk: Object holding the scattered wavevector @type scattk: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword polar: The polar angle and its associated error^2 @type polar: C{tuple} or C{list} of C{tuple}s @keyword units: The expected units for this function. The default for this function is I{1/Angstroms}. @type units: C{string} @return: Object converted to scalar Q @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The C{SOM}-C{SOM} operation is attempted @raise TypeError: The C{SOM}-C{SO} operation is attempted @raise TypeError: The C{SO}-C{SOM} operation is attempted @raise TypeError: The C{SO}-C{SO} operation is attempted @raise RuntimeError: The C{SOM} x-axis units are not I{1/Angstroms} @raise RuntimeError: A C{SOM} is not passed and no polar angle is provided @raise RuntimeError: No C{SOM.Instrument} is provided in a C{SOM} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(initk, scattk) (i_descr, s_descr) = hlr_utils.get_descr(initk, scattk) # error checking for types if i_descr == "SOM" and s_descr == "SOM": raise TypeError("SOM-SOM operation not supported") elif i_descr == "SOM" and s_descr == "SO": raise TypeError("SOM-SO operation not supported") elif i_descr == "SO" and s_descr == "SOM": raise TypeError("SO-SOM operation not supported") elif i_descr == "SO" and s_descr == "SO": raise TypeError("SO-SO operation not supported") else: pass # Setup keyword arguments try: polar = kwargs["polar"] except KeyError: polar = None try: units = kwargs["units"] except KeyError: units = "1/Angstroms" result = hlr_utils.copy_som_attr(result, res_descr, initk, i_descr, scattk, s_descr) if res_descr == "SOM": index = hlr_utils.one_d_units(result, units) result = hlr_utils.force_units(result, units, index) result.setAxisLabel(index, "scalar wavevector transfer") result.setYUnits("Counts/A-1") result.setYLabel("Intensity") else: pass if polar is None: if i_descr == "SOM": try: initk.attr_list.instrument.get_primary() inst = initk.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") elif s_descr == "SOM": try: scattk.attr_list.instrument.get_primary() inst = scattk.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided!") else: raise RuntimeError("If no SOM is provided, then polar "\ +"information must be given.") else: p_descr = hlr_utils.get_descr(polar) # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(initk, scattk)): val1 = hlr_utils.get_value(initk, i, i_descr, "x") err2_1 = hlr_utils.get_err2(initk, i, i_descr, "x") val2 = hlr_utils.get_value(scattk, i, s_descr, "x") err2_2 = hlr_utils.get_err2(scattk, i, s_descr, "x") map_so = hlr_utils.get_map_so(initk, scattk, i) if polar is None: (angle, angle_err2) = hlr_utils.get_parameter("polar", map_so, inst) else: angle = hlr_utils.get_value(polar, i, p_descr) angle_err2 = hlr_utils.get_err2(polar, i, p_descr) value = axis_manip.init_scatt_wavevector_to_scalar_Q( val1, err2_1, val2, err2_2, angle, angle_err2) hlr_utils.result_insert(result, res_descr, value, map_so, "x") return result
def d_spacing_to_tof_focused_det(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from d-spacing to a focused time-of-flight. The focusing is done using the geometry information from a single detector pixel. The d-spacing axis for a C{SOM} must be in units of I{Angstroms}. The primary axis of a C{SO} is assumed to be in units of I{Angstroms}. @param obj: Object to be converted @type obj: C{SOM.SOM} or C{SOM.SO} @param kwargs: A list of keyword arguments that the function accepts: @keyword polar: The polar angle and its associated error^2 @type polar: C{tuple} or C{list} of C{tuple}s @keyword pathlength: The total pathlength and its associated error^2 @type pathlength: C{tuple} or C{list} of C{tuple}s @keyword pixel_id: The pixel ID from which the geometry information will be retrieved from the instrument @type pixel_id: C{tuple}=(\"bankN\", (x, y)) @keyword verbose: This determines if the pixel geometry information is printed. The default is False @type verbose: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds}. @type units: C{string} @return: Object with a primary axis in d-spacing converted to time-of-flight @rtype: C{SOM.SOM} or C{SOM.SO} @raise RuntimeError: A C{SOM} or C{SO} is not provided to the function @raise RuntimeError: No C{SOM.Instrument} is provided in a C{SOM} @raise RuntimeError: No C{SOM} is given and both the pathlength and polar angle are not provided @raise RuntimeError: No C{SOM} is given and the pathlength is not provided @raise RuntimeError: No C{SOM} is given and the polar angle is not provided """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "number" or o_descr == "list": raise RuntimeError("Must provide a SOM of a SO to the function.") # Go on else: pass # Setup keyword arguments try: polar = kwargs["polar"] except KeyError: polar = None try: pathlength = kwargs["pathlength"] except KeyError: pathlength = None try: pixel_id = kwargs["pixel_id"] except KeyError: pixel_id = None try: verbose = kwargs["verbose"] except KeyError: verbose = False try: units = kwargs["units"] except KeyError: units = "Angstroms" # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "microseconds", axis) result.setAxisLabel(axis, "time-of-flight") result.setYUnits("Counts/usec") result.setYLabel("Intensity") else: pass if pathlength is None or polar is None: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("An instrument was not provided") else: if pathlength is None and polar is None: raise RuntimeError("If no SOM is provided, then pathlength "\ +"and polar angle information must be provided") elif pathlength is None: raise RuntimeError("If no SOM is provided, then pathlength "\ +"information must be provided") elif polar is None: raise RuntimeError("If no SOM is provided, then polar angle "\ +"information must be provided") else: raise RuntimeError("If you get here, see Steve Miller for "\ +"your mug.") else: pass if pathlength is not None: p_descr = hlr_utils.get_descr(pathlength) if polar is not None: a_descr = hlr_utils.get_descr(polar) # iterate through the values if pixel_id is not None: tmp_so = SOM.SO() tmp_so.id = pixel_id (pl, pl_err2) = hlr_utils.get_parameter("total", tmp_so, inst) (angle, angle_err2) = hlr_utils.get_parameter("polar", tmp_so, inst) if verbose: format_str = "Pixel ID %s has polar angle: (%f,%f) and " format_str += "pathlength: (%f,%f)" print format_str % (str(pixel_id), angle, angle_err2, pl, pl_err2) else: pass else: pl = hlr_utils.get_value(pathlength, 0, p_descr) pl_err2 = hlr_utils.get_err2(pathlength, 0, p_descr) angle = hlr_utils.get_value(polar, 0, a_descr) angle_err2 = hlr_utils.get_err2(polar, 0, a_descr) # iterate through the values import axis_manip for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) value = axis_manip.d_spacing_to_tof_focused_det(val, err2, pl, pl_err2, angle, angle_err2) hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis) return result
def wavelength_to_velocity(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from wavelength to velocity. The wavelength axis for a C{SOM} must be in units of I{Angstroms}. The primary axis of a C{SO} is assumed to be in units of I{Angstroms}. A C{tuple} of C{(wavelength, wavelength_err2)} (assumed to be in units of I{Angstroms}) can be converted to C{(velocity, velocity_err)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is True for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{Angstroms} @type units: C{string} @return: Object with a primary axis in wavelength converted to velocity @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{Angstroms} """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr == "list": raise TypeError("Do not know how to handle given type: %s" % \ o_descr) else: pass # Setup keyword arguments try: units = kwargs["units"] except KeyError: units = "Angstroms" try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "meters/microseconds", axis) result.setAxisLabel(axis, "velocity") result.setYUnits("Counts/meters/microseconds") result.setYLabel("Intensity") else: pass # iterate through the values import axis_manip if lojac: import utils len_obj = hlr_utils.get_length(obj) for i in xrange(len_obj): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) value = axis_manip.wavelength_to_velocity(val, err2) if lojac: y_val = hlr_utils.get_value(obj, i, o_descr, "y") y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y") counts = utils.linear_order_jacobian(val, value[0], y_val, y_err2) else: pass if o_descr != "number": value1 = axis_manip.reverse_array_cp(value[0]) value2 = axis_manip.reverse_array_cp(value[1]) rev_value = (value1, value2) else: rev_value = value if map_so is not None: if not lojac: map_so.y = axis_manip.reverse_array_cp(map_so.y) map_so.var_y = axis_manip.reverse_array_cp(map_so.var_y) else: map_so.y = axis_manip.reverse_array_cp(counts[0]) map_so.var_y = axis_manip.reverse_array_cp(counts[1]) else: pass hlr_utils.result_insert(result, res_descr, rev_value, map_so, "x", axis) return result
def tof_to_wavelength_lin_time_zero(obj, **kwargs): """ This function converts a primary axis of a C{SOM} or C{SO} from time-of-flight to wavelength incorporating a linear time zero which is a described as a linear function of the wavelength. The time-of-flight axis for a C{SOM} must be in units of I{microseconds}. The primary axis of a C{SO} is assumed to be in units of I{microseconds}. A C{tuple} of C{(tof, tof_err2)} (assumed to be in units of I{microseconds}) can be converted to C{(wavelength, wavelength_err2)}. @param obj: Object to be converted @type obj: C{SOM.SOM}, C{SOM.SO} or C{tuple} @param kwargs: A list of keyword arguments that the function accepts: @keyword pathlength: The pathlength and its associated error^2 @type pathlength: C{tuple} or C{list} of C{tuple}s @keyword time_zero_slope: The time zero slope and its associated error^2 @type time_zero_slope: C{tuple} @keyword time_zero_offset: The time zero offset and its associated error^2 @type time_zero_offset: C{tuple} @keyword inst_param: The type of parameter requested from an associated instrument. For this function the acceptable parameters are I{primary}, I{secondary} and I{total}. Default is I{primary}. @type inst_param: C{string} @keyword lojac: A flag that allows one to turn off the calculation of the linear-order Jacobian. The default action is I{True} for histogram data. @type lojac: C{boolean} @keyword units: The expected units for this function. The default for this function is I{microseconds}. @type units: C{string} @keyword cut_val: Specify a wavelength to cut the spectra at. @type cut_val: C{float} @keyword cut_less: A flag that specifies cutting the spectra less than C{cut_val}. The default is C{True}. @type cut_less: C{boolean} @return: Object with a primary axis in time-of-flight converted to wavelength @rtype: C{SOM.SOM}, C{SOM.SO} or C{tuple} @raise TypeError: The incoming object is not a type the function recognizes @raise RuntimeError: The C{SOM} x-axis units are not I{microseconds} @raise RuntimeError: A C{SOM} does not contain an instrument and no pathlength was provided @raise RuntimeError: No C{SOM} is provided and no pathlength given """ # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) # Setup keyword arguments try: inst_param = kwargs["inst_param"] except KeyError: inst_param = "primary" try: pathlength = kwargs["pathlength"] except KeyError: pathlength = None try: time_zero_slope = kwargs["time_zero_slope"] except KeyError: time_zero_slope = None # Current constants for Time Zero Slope TIME_ZERO_SLOPE = (float(0.0), float(0.0)) try: time_zero_offset = kwargs["time_zero_offset"] except KeyError: time_zero_offset = None # Current constants for Time Zero Offset TIME_ZERO_OFFSET = (float(0.0), float(0.0)) try: lojac = kwargs["lojac"] except KeyError: lojac = hlr_utils.check_lojac(obj) try: units = kwargs["units"] except KeyError: units = "microseconds" try: cut_val = kwargs["cut_val"] except KeyError: cut_val = None try: cut_less = kwargs["cut_less"] except KeyError: cut_less = True # Primary axis for transformation. If a SO is passed, the function, will # assume the axis for transformation is at the 0 position if o_descr == "SOM": axis = hlr_utils.one_d_units(obj, units) else: axis = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result = hlr_utils.force_units(result, "Angstroms", axis) result.setAxisLabel(axis, "wavelength") result.setYUnits("Counts/A") result.setYLabel("Intensity") else: pass if pathlength is not None: p_descr = hlr_utils.get_descr(pathlength) else: if o_descr == "SOM": try: obj.attr_list.instrument.get_primary() inst = obj.attr_list.instrument except RuntimeError: raise RuntimeError("A detector was not provided") else: raise RuntimeError("If no SOM is provided, then pathlength "\ +"information must be provided") if time_zero_slope is not None: t_0_slope_descr = hlr_utils.get_descr(time_zero_slope) else: if o_descr == "SOM": try: t_0_slope = obj.attr_list["Time_zero_slope"][0] t_0_slope_err2 = obj.attr_list["Time_zero_slope"][1] except KeyError: t_0_slope = TIME_ZERO_SLOPE[0] t_0_slope_err2 = TIME_ZERO_SLOPE[1] else: t_0_slope = TIME_ZERO_SLOPE[0] t_0_slope_err2 = TIME_ZERO_SLOPE[1] if time_zero_offset is not None: t_0_offset_descr = hlr_utils.get_descr(time_zero_offset) else: if o_descr == "SOM": try: t_0_offset = obj.attr_list["Time_zero_offset"][0] t_0_offset_err2 = obj.attr_list["Time_zero_offset"][1] except KeyError: t_0_offset = TIME_ZERO_OFFSET[0] t_0_offset_err2 = TIME_ZERO_OFFSET[1] else: t_0_offset = TIME_ZERO_OFFSET[0] t_0_offset_err2 = TIME_ZERO_OFFSET[1] # iterate through the values import axis_manip if lojac or cut_val is not None: import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if pathlength is None: (pl, pl_err2) = hlr_utils.get_parameter(inst_param, map_so, inst) else: pl = hlr_utils.get_value(pathlength, i, p_descr) pl_err2 = hlr_utils.get_err2(pathlength, i, p_descr) if time_zero_slope is not None: t_0_slope = hlr_utils.get_value(time_zero_slope, i, t_0_slope_descr) t_0_slope_err2 = hlr_utils.get_err2(time_zero_slope, i, t_0_slope_descr) else: pass if time_zero_offset is not None: t_0_offset = hlr_utils.get_value(time_zero_offset, i, t_0_offset_descr) t_0_offset_err2 = hlr_utils.get_err2(time_zero_offset, i, t_0_offset_descr) else: pass value = axis_manip.tof_to_wavelength_lin_time_zero( val, err2, pl, pl_err2, t_0_slope, t_0_slope_err2, t_0_offset, t_0_offset_err2) if cut_val is not None: index = utils.bisect_helper(value[0], cut_val) if cut_less: # Need to cut at this index, so increment by one index += 1 value[0].__delslice__(0, index) value[1].__delslice__(0, index) map_so.y.__delslice__(0, index) map_so.var_y.__delslice__(0, index) if lojac: val.__delslice__(0, index) err2.__delslice__(0, index) else: len_data = len(value[0]) # All axis arrays need starting index adjusted by one since # they always carry one more bin than the data value[0].__delslice__(index + 1, len_data) value[1].__delslice__(index + 1, len_data) map_so.y.__delslice__(index, len_data) map_so.var_y.__delslice__(index, len_data) if lojac: val.__delslice__(index + 1, len_data) err2.__delslice__(index + 1, len_data) if lojac: counts = utils.linear_order_jacobian(val, value[0], map_so.y, map_so.var_y) hlr_utils.result_insert(result, res_descr, counts, map_so, "all", axis, [value[0]]) else: hlr_utils.result_insert(result, res_descr, value, map_so, "x", axis) return result
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
def energy_transfer(obj, itype, axis_const, **kwargs): """ This function takes a SOM with a wavelength axis (initial for IGS and final for DGS) and calculates the energy transfer. @param obj: The object containing the wavelength axis @type obj: C{SOM.SOM} @param itype: The instrument class type. The choices are either I{IGS} or I{DGS}. @type itype: C{string} @param axis_const: The attribute name for the axis constant which is the final wavelength for I{IGS} and the initial energy for I{DGS}. @type axis_const: C{string} @param kwargs: A list of keyword arguments that the function accepts: @keyword units: The units for the incoming axis. The default is I{Angstroms}. @type units: C{string} @keyword change_units: A flag that signals the function to convert from I{meV} to I{ueV}. The default is I{False}. @type change_units: C{boolean} @keyword scale: A flag to scale the y-axis by lambda_f/lambda_i for I{IGS} and lambda_i/lambda_f for I{DGS}. The default is I{False}. @type scale: C{boolean} @keyword lojac: A flag that turns on the calculation and application of the linear-order Jacobian. The default is I{False}. @type lojac: C{boolean} @keyword sa_norm: A flag to turn on solid angle normlaization. @type sa_norm: C{boolean} @return: Object with the energy transfer calculated in units of I{meV} or I{ueV}. The default is I{meV}. @rtype: C{SOM.SOM} @raise RuntimeError: The instrument class type is not recognized @raise RuntimeError: The x-axis units are not Angstroms @raise RuntimeError: A SOM is not given to the function """ # Check the instrument class type to make sure its allowed allowed_types = ["DGS", "IGS"] if itype not in allowed_types: raise RuntimeError("The instrument class type %s is not known. "\ +"Please use DGS or IGS" % itype) # import the helper functions import hlr_utils # set up for working through data (result, res_descr) = hlr_utils.empty_result(obj) o_descr = hlr_utils.get_descr(obj) if o_descr != "SOM": raise RuntimeError("Must provide a SOM to the function.") # Go on else: pass # Setup keyword arguments try: units = kwargs["units"] except KeyError: units = "Angstroms" try: change_units = kwargs["change_units"] except KeyError: change_units = False try: scale = kwargs["scale"] except KeyError: scale = False try: sa_norm = kwargs["sa_norm"] except KeyError: sa_norm = False if sa_norm: inst = obj.attr_list.instrument try: lojac = kwargs["lojac"] except KeyError: lojac = False # Primary axis for transformation. axis = hlr_utils.one_d_units(obj, units) # Get the subtraction constant try: axis_c = obj.attr_list[axis_const] except KeyError: raise RuntimeError("Must provide a final wavelength (IGS) or initial "\ +"energy (DGS) via the incoming SOM") result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if change_units: unit_str = "ueV" else: unit_str = "meV" result = hlr_utils.force_units(result, unit_str, axis) result.setAxisLabel(axis, "energy_transfer") result.setYUnits("Counts/" + unit_str) result.setYLabel("Intensity") # iterate through the values import array_manip import axis_manip import dr_lib import utils for i in xrange(hlr_utils.get_length(obj)): if itype == "IGS": l_i = hlr_utils.get_value(obj, i, o_descr, "x", axis) l_i_err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) else: l_f = hlr_utils.get_value(obj, i, o_descr, "x", axis) l_f_err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) y_val = hlr_utils.get_value(obj, i, o_descr, "y", axis) y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y", axis) map_so = hlr_utils.get_map_so(obj, None, i) if itype == "IGS": (E_i, E_i_err2) = axis_manip.wavelength_to_energy(l_i, l_i_err2) l_f = hlr_utils.get_special(axis_c, map_so)[:2] (E_f, E_f_err2) = axis_manip.wavelength_to_energy(l_f[0], l_f[1]) if lojac: (y_val, y_err2) = utils.linear_order_jacobian(l_i, E_i, y_val, y_err2) else: (E_i, E_i_err2) = axis_c.toValErrTuple() (E_f, E_f_err2) = axis_manip.wavelength_to_energy(l_f, l_f_err2) if lojac: (y_val, y_err2) = utils.linear_order_jacobian(l_f, E_f, y_val, y_err2) if scale: # Scale counts by lambda_f / lambda_i if itype == "IGS": (l_n, l_n_err2) = l_f (l_d, l_d_err2) = utils.calc_bin_centers(l_i, l_i_err2) else: (l_n, l_n_err2) = utils.calc_bin_centers(l_f, l_f_err2) (l_d, l_d_err2) = axis_manip.energy_to_wavelength(E_i, E_i_err2) ratio = array_manip.div_ncerr(l_n, l_n_err2, l_d, l_d_err2) scale_y = array_manip.mult_ncerr(y_val, y_err2, ratio[0], ratio[1]) else: scale_y = (y_val, y_err2) value = array_manip.sub_ncerr(E_i, E_i_err2, E_f, E_f_err2) if change_units: # Convert from meV to ueV value2 = array_manip.mult_ncerr(value[0], value[1], 1000.0, 0.0) scale_y = array_manip.mult_ncerr(scale_y[0], scale_y[1], 1.0 / 1000.0, 0.0) else: value2 = value if sa_norm: if inst.get_name() == "BSS": dOmega = dr_lib.calc_BSS_solid_angle(map_so, inst) scale_y = array_manip.div_ncerr(scale_y[0], scale_y[1], dOmega, 0.0) else: raise RuntimeError("Do not know how to get solid angle from "\ +"%s" % inst.get_name()) if itype == "IGS": # Reverse the values due to the conversion value_y = axis_manip.reverse_array_cp(scale_y[0]) value_var_y = axis_manip.reverse_array_cp(scale_y[1]) value_x = axis_manip.reverse_array_cp(value2[0]) else: value_y = scale_y[0] value_var_y = scale_y[1] value_x = value2[0] hlr_utils.result_insert(result, res_descr, (value_y, value_var_y), map_so, "all", 0, [value_x]) return result