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 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 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 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 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 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 dimensionless_mon(obj, min_ext, max_ext, **kwargs): """ This function takes monitor spectra and converts them to dimensionless spectra by dividing each spectrum by the total number of counts within the range [min_ext, max_ext]. Then, each spectrum is multiplied by the quantity max_ext - min_ext. The units of min_ext and max_ext are assumed to be the same as the monitor spectra axis. @param obj: Object containing monitor spectra @type obj: C{SOM.SOM} or C{SOM.SO} @param min_ext: Minimium range and associated error^2 for integrating total counts. @type min_ext: C{tuple} @param max_ext: Maximium range and associated error^2 for integrating total counts. @type max_ext: 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: Dimensionless monitor spectra @rtype: C{SOM.SOM} or C{SOM.SO} """ # import the helper functions import hlr_utils if obj is None: return obj # 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 = "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) import array_manip import dr_lib import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "y") err2 = hlr_utils.get_err2(obj, i, o_descr, "y") x_axis = hlr_utils.get_value(obj, i, o_descr, "x", axis) x_err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) bin_widths = utils.calc_bin_widths(x_axis, x_err2) # Scale bin contents by bin width value0 = array_manip.mult_ncerr(val, err2, bin_widths[0], bin_widths[1]) # Find bin range for extents min_index = utils.bisect_helper(x_axis, min_ext[0]) max_index = utils.bisect_helper(x_axis, max_ext[0]) # Integrate axis using bin width multiplication (asum, asum_err2) = dr_lib.integrate_axis_py(map_so, start=min_index, end=max_index, width=True) # Get the number of bins in the integration range num_bins = max_index - min_index + 1 asum /= num_bins asum_err2 /= (num_bins * num_bins) # Divide by sum value1 = array_manip.div_ncerr(value0[0], value0[1], asum, asum_err2) hlr_utils.result_insert(result, res_descr, value1, map_so, "y") return result
def calc_substrate_trans(obj, subtrans_coeff, substrate_diam, **kwargs): """ This function calculates substrate transmission via the following formula: T = exp[-(A + B * wavelength) * d] where A is a constant with units of cm^-1, B is a constant with units of cm^-2 and d is the substrate diameter in units of cm. @param obj: The data object that contains the TOF axes to calculate the transmission from. @type obj: C{SOM.SOM} or C{SOM.SO} @param subtrans_coeff: The two coefficients for substrate transmission calculation. @type subtrans_coeff: C{tuple} of two C{float}s @param substrate_diam: The diameter of the substrate. @type substrate_diam: C{float} @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 units: The expected units for this function. The default for this function is I{microsecond}. @type units: C{string} @return: The calculate transmission for the given substrate parameters @rtype: C{SOM.SOM} or C{SOM.SO} @raise TypeError: The object used for calculation is not a C{SOM} or a C{SO} @raise RuntimeError: The C{SOM} x-axis units are not I{microsecond} @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) if o_descr == "number" or o_descr == "list": raise TypeError("Do not know how to handle given type: %s" % o_descr) else: pass # Setup keyword arguments try: pathlength = kwargs["pathlength"] except KeyError: pathlength = None try: units = kwargs["units"] except KeyError: units = "microsecond" # 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 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") result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result.setYLabel("Transmission") # iterate through the values import array_manip import axis_manip import nessi_list import utils import math 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 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) value = axis_manip.tof_to_wavelength(val, err2, pl, pl_err2) value1 = utils.calc_bin_centers(value[0]) del value # Convert Angstroms to centimeters value2 = array_manip.mult_ncerr(value1[0], value1[1], subtrans_coeff[1] * 1.0e-8, 0.0) del value1 # Calculate the exponential value3 = array_manip.add_ncerr(value2[0], value2[1], subtrans_coeff[0], 0.0) del value2 value4 = array_manip.mult_ncerr(value3[0], value3[1], -1.0 * substrate_diam, 0.0) del value3 # Calculate transmission trans = nessi_list.NessiList() len_trans = len(value4[0]) for j in xrange(len_trans): trans.append(math.exp(value4[0][j])) trans_err2 = nessi_list.NessiList(len(trans)) hlr_utils.result_insert(result, res_descr, (trans, trans_err2), map_so) 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 feff_correct_mon(obj, **kwargs): """ This function takes in a monitor spectra, calculates efficiencies based on the montior's wavelength axis and divides the monitor counts by the calculated efficiencies. The function is a M{constant * wavelength}. @param obj: Object containing monitor spectra @type obj: 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} @keyword eff_const: Use this provided effieciency constant. The default is (0.00000085 / 1.8) Angstroms^-1. @type eff_const: L{hlr_utils.DrParameter} @keyword inst_name: The short name of an instrument. @type inst_name: C{string} @return: Efficiency corrected monitor spectra @rtype: C{SOM.SOM} or C{SOM.SO} """ # import the helper functions import hlr_utils if obj is None: return obj # 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 = "Angstroms" try: eff_const = kwargs["eff_const"] except KeyError: # This is for SNS (specifically BASIS) monitors eff_const = hlr_utils.DrParameter((0.00000085 / 1.8), 0.0, "Angstroms^-1") # A^-1 inst_name = kwargs.get("inst_name") # 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) # iterate through the values import array_manip import nessi_list import dr_lib for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if inst_name is None: eff = nessi_list.NessiList() for j in xrange(len(val)-1): bin_center = (val[j+1] + val[j]) / 2.0 eff.append(eff_const.getValue() * bin_center) eff_err2 = nessi_list.NessiList(len(eff)) else: if inst_name == "SANS": (eff, eff_err2) = dr_lib.subexp_eff(eff_const, val) else: raise RuntimeError("Do not know how to handle %s instrument" \ % inst_name) y_val = hlr_utils.get_value(obj, i, o_descr, "y") y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y") value = array_manip.div_ncerr(y_val, y_err2, eff, eff_err2) hlr_utils.result_insert(result, res_descr, value, map_so, "y") 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_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 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 fix_bin_contents(obj, **kwargs): """ This function takes a SOM or SO and goes through the individual spectra adjusting the bin contents by either multiplying or dividing by the bin widths or the bin centers taken from the individual spectra. @param obj: The data object to be scaled @type obj: C{SOM.SOM} or C{SOM.SO} @param kwargs: A list of keyword arguments that the function accepts: @keyword scale: A flag that signals multiplication by the required bin quantity. The default is I{False} (divide). @type scale: C{bool} @keyword width: A flag that signals that the adjusting quantity is the bin width. The default is I{True}. If I{False}, the bin center is used. @type width: C{bool} @keyword units: The expected units for this function. The default for this function is I{microsecond}. @type units: C{string} @return: The object with the individual spectrum scaled @rtype: C{SOM.SOM} or C{SOM.SO} """ 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: scale = kwargs["scale"] except KeyError: scale = False try: width = kwargs["width"] except KeyError: width = True try: units = kwargs["units"] except KeyError: units = "microsecond" # 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_pos = hlr_utils.one_d_units(obj, units) else: axis_pos = 0 result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) # iterate through the values import array_manip import utils for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "y") err2 = hlr_utils.get_err2(obj, i, o_descr, "y") axis = hlr_utils.get_value(obj, i, o_descr, "x", axis_pos) axis_err2 = hlr_utils.get_err2(obj, i, o_descr, "x", axis_pos) map_so = hlr_utils.get_map_so(obj, None, i) if width: (bin_const, bin_const_err2) = utils.calc_bin_widths(axis, axis_err2) else: (bin_const, bin_const_err2) = utils.calc_bin_centers(axis, axis_err2) if scale: value = array_manip.mult_ncerr(val, err2, bin_const, bin_const_err2) else: value = array_manip.div_ncerr(val, err2, bin_const, bin_const_err2) hlr_utils.result_insert(result, res_descr, value, map_so, "y") return result
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 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 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(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 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 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 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 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 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 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 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 calc_substrate_trans(obj, subtrans_coeff, substrate_diam, **kwargs): """ This function calculates substrate transmission via the following formula: T = exp[-(A + B * wavelength) * d] where A is a constant with units of cm^-1, B is a constant with units of cm^-2 and d is the substrate diameter in units of cm. @param obj: The data object that contains the TOF axes to calculate the transmission from. @type obj: C{SOM.SOM} or C{SOM.SO} @param subtrans_coeff: The two coefficients for substrate transmission calculation. @type subtrans_coeff: C{tuple} of two C{float}s @param substrate_diam: The diameter of the substrate. @type substrate_diam: C{float} @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 units: The expected units for this function. The default for this function is I{microsecond}. @type units: C{string} @return: The calculate transmission for the given substrate parameters @rtype: C{SOM.SOM} or C{SOM.SO} @raise TypeError: The object used for calculation is not a C{SOM} or a C{SO} @raise RuntimeError: The C{SOM} x-axis units are not I{microsecond} @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) if o_descr == "number" or o_descr == "list": raise TypeError("Do not know how to handle given type: %s" % o_descr) else: pass # Setup keyword arguments try: pathlength = kwargs["pathlength"] except KeyError: pathlength = None try: units = kwargs["units"] except KeyError: units = "microsecond" # 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 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") result = hlr_utils.copy_som_attr(result, res_descr, obj, o_descr) if res_descr == "SOM": result.setYLabel("Transmission") # iterate through the values import array_manip import axis_manip import nessi_list import utils import math 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 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) value = axis_manip.tof_to_wavelength(val, err2, pl, pl_err2) value1 = utils.calc_bin_centers(value[0]) del value # Convert Angstroms to centimeters value2 = array_manip.mult_ncerr(value1[0], value1[1], subtrans_coeff[1]*1.0e-8, 0.0) del value1 # Calculate the exponential value3 = array_manip.add_ncerr(value2[0], value2[1], subtrans_coeff[0], 0.0) del value2 value4 = array_manip.mult_ncerr(value3[0], value3[1], -1.0*substrate_diam, 0.0) del value3 # Calculate transmission trans = nessi_list.NessiList() len_trans = len(value4[0]) for j in xrange(len_trans): trans.append(math.exp(value4[0][j])) trans_err2 = nessi_list.NessiList(len(trans)) hlr_utils.result_insert(result, res_descr, (trans, trans_err2), map_so) return result
def feff_correct_mon(obj, **kwargs): """ This function takes in a monitor spectra, calculates efficiencies based on the montior's wavelength axis and divides the monitor counts by the calculated efficiencies. The function is a M{constant * wavelength}. @param obj: Object containing monitor spectra @type obj: 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} @keyword eff_const: Use this provided effieciency constant. The default is (0.00000085 / 1.8) Angstroms^-1. @type eff_const: L{hlr_utils.DrParameter} @keyword inst_name: The short name of an instrument. @type inst_name: C{string} @return: Efficiency corrected monitor spectra @rtype: C{SOM.SOM} or C{SOM.SO} """ # import the helper functions import hlr_utils if obj is None: return obj # 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 = "Angstroms" try: eff_const = kwargs["eff_const"] except KeyError: # This is for SNS (specifically BASIS) monitors eff_const = hlr_utils.DrParameter((0.00000085 / 1.8), 0.0, "Angstroms^-1") # A^-1 inst_name = kwargs.get("inst_name") # 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) # iterate through the values import array_manip import nessi_list import dr_lib for i in xrange(hlr_utils.get_length(obj)): val = hlr_utils.get_value(obj, i, o_descr, "x", axis) map_so = hlr_utils.get_map_so(obj, None, i) if inst_name is None: eff = nessi_list.NessiList() for j in xrange(len(val) - 1): bin_center = (val[j + 1] + val[j]) / 2.0 eff.append(eff_const.getValue() * bin_center) eff_err2 = nessi_list.NessiList(len(eff)) else: if inst_name == "SANS": (eff, eff_err2) = dr_lib.subexp_eff(eff_const, val) else: raise RuntimeError("Do not know how to handle %s instrument" \ % inst_name) y_val = hlr_utils.get_value(obj, i, o_descr, "y") y_err2 = hlr_utils.get_err2(obj, i, o_descr, "y") value = array_manip.div_ncerr(y_val, y_err2, eff, eff_err2) hlr_utils.result_insert(result, res_descr, value, map_so, "y") 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 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