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 create_E_vs_Q_igs(som, *args, **kwargs): """ This function starts with the initial IGS wavelength axis and turns this into a 2D spectra with E and Q axes. @param som: The input object with initial IGS wavelength axis @type som: C{SOM.SOM} @param args: A mandatory list of axes for rebinning. There is a particular order to them. They should be present in the following order: Without errors 1. Energy transfer 2. Momentum transfer With errors 1. Energy transfer 2. Energy transfer error^2 3. Momentum transfer 4. Momentum transfer error ^2 @type args: C{nessi_list.NessiList}s @param kwargs: A list of keyword arguments that the function accepts: @keyword withXVar: Flag for whether the function should be expecting the associated axes to have errors. The default value will be I{False}. @type withXVar: C{boolean} @keyword data_type: Name of the data type which can be either I{histogram}, I{density} or I{coordinate}. The default value will be I{histogram} @type data_type: C{string} @keyword Q_filter: Flag to turn on or off Q filtering. The default behavior is I{True}. @type Q_filter: C{boolean} @keyword so_id: The identifier represents a number, string, tuple or other object that describes the resulting C{SO} @type so_id: C{int}, C{string}, C{tuple}, C{pixel ID} @keyword y_label: The y axis label @type y_label: C{string} @keyword y_units: The y axis units @type y_units: C{string} @keyword x_labels: This is a list of names that sets the individual x axis labels @type x_labels: C{list} of C{string}s @keyword x_units: This is a list of names that sets the individual x axis units @type x_units: C{list} of C{string}s @keyword split: This flag causes the counts and the fractional area to be written out into separate files. @type split: C{boolean} @keyword configure: This is the object containing the driver configuration. @type configure: C{Configure} @return: Object containing a 2D C{SO} with E and Q axes @rtype: C{SOM.SOM} @raise RuntimeError: Anything other than a C{SOM} is passed to the function @raise RuntimeError: An instrument is not contained in the C{SOM} """ import nessi_list # Setup some variables dim = 2 N_y = [] N_tot = 1 N_args = len(args) # Get T0 slope in order to calculate dT = dT_i + dT_0 try: t_0_slope = som.attr_list["Time_zero_slope"][0] t_0_slope_err2 = som.attr_list["Time_zero_slope"][1] except KeyError: t_0_slope = float(0.0) t_0_slope_err2 = float(0.0) # Check withXVar keyword argument and also check number of given args. # Set xvar to the appropriate value try: value = kwargs["withXVar"] if value.lower() == "true": if N_args != 4: raise RuntimeError("Since you have requested x errors, 4 x "\ +"axes must be provided.") else: xvar = True elif value.lower() == "false": if N_args != 2: raise RuntimeError("Since you did not requested x errors, 2 "\ +"x axes must be provided.") else: xvar = False else: raise RuntimeError("Do not understand given parameter %s" % \ value) except KeyError: if N_args != 2: raise RuntimeError("Since you did not requested x errors, 2 "\ +"x axes must be provided.") else: xvar = False # Check dataType keyword argument. An offset will be set to 1 for the # histogram type and 0 for either density or coordinate try: data_type = kwargs["data_type"] if data_type.lower() == "histogram": offset = 1 elif data_type.lower() == "density" or \ data_type.lower() == "coordinate": offset = 0 else: raise RuntimeError("Do not understand data type given: %s" % \ data_type) # Default is offset for histogram except KeyError: offset = 1 try: Q_filter = kwargs["Q_filter"] except KeyError: Q_filter = True # Check for split keyword try: split = kwargs["split"] except KeyError: split = False # Check for configure keyword try: configure = kwargs["configure"] except KeyError: configure = None so_dim = SOM.SO(dim) for i in range(dim): # Set the x-axis arguments from the *args list into the new SO if not xvar: # Axis positions are 1 (Q) and 0 (E) position = dim - i - 1 so_dim.axis[i].val = args[position] else: # Axis positions are 2 (Q), 3 (eQ), 0 (E), 1 (eE) position = dim - 2 * i so_dim.axis[i].val = args[position] so_dim.axis[i].var = args[position + 1] # Set individual value axis sizes (not x-axis size) N_y.append(len(args[position]) - offset) # Calculate total 2D array size N_tot = N_tot * N_y[-1] # Create y and var_y lists from total 2D size so_dim.y = nessi_list.NessiList(N_tot) so_dim.var_y = nessi_list.NessiList(N_tot) # Create area sum and errors for the area sum lists from total 2D size area_sum = nessi_list.NessiList(N_tot) area_sum_err2 = nessi_list.NessiList(N_tot) # Create area sum and errors for the area sum lists from total 2D size bin_count = nessi_list.NessiList(N_tot) bin_count_err2 = nessi_list.NessiList(N_tot) inst = som.attr_list.instrument lambda_final = som.attr_list["Wavelength_final"] inst_name = inst.get_name() import bisect import math import dr_lib import utils arr_len = 0 #: Vector of zeros for function calculations zero_vec = None for j in xrange(hlr_utils.get_length(som)): # Get counts counts = hlr_utils.get_value(som, j, "SOM", "y") counts_err2 = hlr_utils.get_err2(som, j, "SOM", "y") arr_len = len(counts) zero_vec = nessi_list.NessiList(arr_len) # Get mapping SO map_so = hlr_utils.get_map_so(som, None, j) # Get lambda_i l_i = hlr_utils.get_value(som, j, "SOM", "x") l_i_err2 = hlr_utils.get_err2(som, j, "SOM", "x") # Get lambda_f from instrument information l_f_tuple = hlr_utils.get_special(lambda_final, map_so) l_f = l_f_tuple[0] l_f_err2 = l_f_tuple[1] # Get source to sample distance (L_s, L_s_err2) = hlr_utils.get_parameter("primary", map_so, inst) # Get sample to detector distance L_d_tuple = hlr_utils.get_parameter("secondary", map_so, inst) L_d = L_d_tuple[0] # Get polar angle from instrument information (angle, angle_err2) = hlr_utils.get_parameter("polar", map_so, inst) # Get the detector pixel height dh_tuple = hlr_utils.get_parameter("dh", map_so, inst) dh = dh_tuple[0] # Need dh in units of Angstrom dh *= 1e10 # Calculate T_i (T_i, T_i_err2) = axis_manip.wavelength_to_tof(l_i, l_i_err2, L_s, L_s_err2) # Scale counts by lambda_f / lambda_i (l_i_bc, l_i_bc_err2) = utils.calc_bin_centers(l_i, l_i_err2) (ratio, ratio_err2) = array_manip.div_ncerr(l_f, l_f_err2, l_i_bc, l_i_bc_err2) (counts, counts_err2) = array_manip.mult_ncerr(counts, counts_err2, ratio, ratio_err2) # Calculate E_i (E_i, E_i_err2) = axis_manip.wavelength_to_energy(l_i, l_i_err2) # Calculate E_f (E_f, E_f_err2) = axis_manip.wavelength_to_energy(l_f, l_f_err2) # Calculate E_t (E_t, E_t_err2) = array_manip.sub_ncerr(E_i, E_i_err2, E_f, E_f_err2) if inst_name == "BSS": # Convert E_t from meV to ueV (E_t, E_t_err2) = array_manip.mult_ncerr(E_t, E_t_err2, 1000.0, 0.0) (counts, counts_err2) = array_manip.mult_ncerr(counts, counts_err2, 1.0/1000.0, 0.0) # Convert lambda_i to k_i (k_i, k_i_err2) = axis_manip.wavelength_to_scalar_k(l_i, l_i_err2) # Convert lambda_f to k_f (k_f, k_f_err2) = axis_manip.wavelength_to_scalar_k(l_f, l_f_err2) # Convert k_i and k_f to Q (Q, Q_err2) = axis_manip.init_scatt_wavevector_to_scalar_Q(k_i, k_i_err2, k_f, k_f_err2, angle, angle_err2) # Calculate dT = dT_0 + dT_i dT_i = utils.calc_bin_widths(T_i, T_i_err2) (l_i_bw, l_i_bw_err2) = utils.calc_bin_widths(l_i, l_i_err2) dT_0 = array_manip.mult_ncerr(l_i_bw, l_i_bw_err2, t_0_slope, t_0_slope_err2) dT_tuple = array_manip.add_ncerr(dT_i[0], dT_i[1], dT_0[0], dT_0[1]) dT = dT_tuple[0] # Calculate Jacobian if inst_name == "BSS": (x_1, x_2, x_3, x_4) = dr_lib.calc_BSS_coeffs(map_so, inst, (E_i, E_i_err2), (Q, Q_err2), (k_i, k_i_err2), (T_i, T_i_err2), dh, angle, E_f, k_f, l_f, L_s, L_d, t_0_slope, zero_vec) else: raise RuntimeError("Do not know how to calculate x_i "\ +"coefficients for instrument %s" % inst_name) (A, A_err2) = dr_lib.calc_EQ_Jacobian(x_1, x_2, x_3, x_4, dT, dh, zero_vec) # Apply Jacobian: C/dlam * dlam / A(EQ) = C/EQ (jac_ratio, jac_ratio_err2) = array_manip.div_ncerr(l_i_bw, l_i_bw_err2, A, A_err2) (counts, counts_err2) = array_manip.mult_ncerr(counts, counts_err2, jac_ratio, jac_ratio_err2) # Reverse counts, E_t, k_i and Q E_t = axis_manip.reverse_array_cp(E_t) E_t_err2 = axis_manip.reverse_array_cp(E_t_err2) Q = axis_manip.reverse_array_cp(Q) Q_err2 = axis_manip.reverse_array_cp(Q_err2) counts = axis_manip.reverse_array_cp(counts) counts_err2 = axis_manip.reverse_array_cp(counts_err2) k_i = axis_manip.reverse_array_cp(k_i) x_1 = axis_manip.reverse_array_cp(x_1) x_2 = axis_manip.reverse_array_cp(x_2) x_3 = axis_manip.reverse_array_cp(x_3) x_4 = axis_manip.reverse_array_cp(x_4) dT = axis_manip.reverse_array_cp(dT) # Filter for duplicate Q values if Q_filter: k_i_cutoff = k_f * math.cos(angle) k_i_cutbin = bisect.bisect(k_i, k_i_cutoff) counts.__delslice__(0, k_i_cutbin) counts_err2.__delslice__(0, k_i_cutbin) Q.__delslice__(0, k_i_cutbin) Q_err2.__delslice__(0, k_i_cutbin) E_t.__delslice__(0, k_i_cutbin) E_t_err2.__delslice__(0, k_i_cutbin) x_1.__delslice__(0, k_i_cutbin) x_2.__delslice__(0, k_i_cutbin) x_3.__delslice__(0, k_i_cutbin) x_4.__delslice__(0, k_i_cutbin) dT.__delslice__(0, k_i_cutbin) zero_vec.__delslice__(0, k_i_cutbin) try: if inst_name == "BSS": ((Q_1, E_t_1), (Q_2, E_t_2), (Q_3, E_t_3), (Q_4, E_t_4)) = dr_lib.calc_BSS_EQ_verticies((E_t, E_t_err2), (Q, Q_err2), x_1, x_2, x_3, x_4, dT, dh, zero_vec) else: raise RuntimeError("Do not know how to calculate (Q_i, "\ +"E_t_i) verticies for instrument %s" \ % inst_name) except IndexError: # All the data got Q filtered, move on continue try: (y_2d, y_2d_err2, area_new, bin_count_new) = axis_manip.rebin_2D_quad_to_rectlin(Q_1, E_t_1, Q_2, E_t_2, Q_3, E_t_3, Q_4, E_t_4, counts, counts_err2, so_dim.axis[0].val, so_dim.axis[1].val) except IndexError, e: # Get the offending index from the error message index = int(str(e).split()[1].split('index')[-1].strip('[]')) print "Id:", map_so.id print "Index:", index print "Verticies: %f, %f, %f, %f, %f, %f, %f, %f" % (Q_1[index], E_t_1[index], Q_2[index], E_t_2[index], Q_3[index], E_t_3[index], Q_4[index], E_t_4[index]) raise IndexError(str(e)) # Add in together with previous results (so_dim.y, so_dim.var_y) = array_manip.add_ncerr(so_dim.y, so_dim.var_y, y_2d, y_2d_err2) (area_sum, area_sum_err2) = array_manip.add_ncerr(area_sum, area_sum_err2, area_new, area_sum_err2) if configure.dump_pix_contrib or configure.scale_sqe: if inst_name == "BSS": dOmega = dr_lib.calc_BSS_solid_angle(map_so, inst) (bin_count_new, bin_count_err2) = array_manip.mult_ncerr(bin_count_new, bin_count_err2, dOmega, 0.0) (bin_count, bin_count_err2) = array_manip.add_ncerr(bin_count, bin_count_err2, bin_count_new, bin_count_err2) else: del bin_count_new
def create_Qvec_vs_E_dgs(som, E_i, conf, **kwargs): """ This function starts with the energy transfer axis from DGS reduction and turns this into a 4D spectra with Qx, Qy, Qz and Et axes. @param som: The input object with initial IGS wavelength axis @type som: C{SOM.SOM} @param E_i: The initial energy for the given data. @type E_i: C{tuple} @param conf: Object that contains the current setup of the driver. @type conf: L{hlr_utils.Configure} @param kwargs: A list of keyword arguments that the function accepts: @keyword timer: Timing object so the function can perform timing estimates. @type timer: C{sns_timer.DiffTime} @keyword corner_angles: The object that contains the corner geometry information. @type corner_angles: C{dict} @keyword make_fixed: A flag that turns on writing the fixed grid mesh information to a file. @type make_fixed: C{boolean} @keyword output: The output filename and or directory. @type output: C{string} """ import array_manip import axis_manip import common_lib import hlr_utils import os # Check keywords try: t = kwargs["timer"] except KeyError: t = None corner_angles = kwargs["corner_angles"] try: make_fixed = kwargs["make_fixed"] except KeyError: make_fixed = False try: output = kwargs["output"] except KeyError: output = None # Convert initial energy to initial wavevector l_i = common_lib.energy_to_wavelength(E_i) k_i = common_lib.wavelength_to_scalar_k(l_i) # Since all the data is rebinned to the same energy transfer axis, we can # calculate the final energy axis once E_t = som[0].axis[0].val if som[0].axis[0].var is not None: E_t_err2 = som[0].axis[0].var else: import nessi_list E_t_err2 = nessi_list.NessiList(len(E_t)) E_f = array_manip.sub_ncerr(E_i[0], E_i[1], E_t, E_t_err2) # Check for negative final energies which will cause problems with # wavelength conversion due to square root if E_f[0][-1] < 0: E_f[0].reverse() E_f[1].reverse() index = 0 for E in E_f[0]: if E >= 0: break index += 1 E_f[0].__delslice__(0, index) E_f[1].__delslice__(0, index) E_f[0].reverse() E_f[1].reverse() len_E = len(E_f[0]) - 1 # Now we can get the final wavevector l_f = axis_manip.energy_to_wavelength(E_f[0], E_f[1]) k_f = axis_manip.wavelength_to_scalar_k(l_f[0], l_f[1]) # Grab the instrument from the som inst = som.attr_list.instrument if make_fixed: import SOM fixed_grid = {} for key in corner_angles: so_id = SOM.NeXusId.fromString(key).toTuple() try: pathlength = inst.get_secondary(so_id)[0] points = [] for j in range(4): points.extend( __calc_xyz(pathlength, corner_angles[key].getPolar(j), corner_angles[key].getAzimuthal(j))) fixed_grid[key] = points except KeyError: # Pixel ID is not in instrument geometry pass CNT = {} ERR2 = {} V1 = {} V2 = {} V3 = {} V4 = {} # Output positions for Qx, Qy, Qz coordinates X = 0 Y = 2 Z = 4 if t is not None: t.getTime(False) # Iterate though the data len_som = hlr_utils.get_length(som) for i in xrange(len_som): map_so = hlr_utils.get_map_so(som, None, i) yval = hlr_utils.get_value(som, i, "SOM", "y") yerr2 = hlr_utils.get_err2(som, i, "SOM", "y") CNT[str(map_so.id)] = yval ERR2[str(map_so.id)] = yerr2 cangles = corner_angles[str(map_so.id)] Q1 = axis_manip.init_scatt_wavevector_to_Q(k_i[0], k_i[1], k_f[0], k_f[1], cangles.getAzimuthal(0), 0.0, cangles.getPolar(0), 0.0) V1[str(map_so.id)] = {} V1[str(map_so.id)]["x"] = Q1[X] V1[str(map_so.id)]["y"] = Q1[Y] V1[str(map_so.id)]["z"] = Q1[Z] Q2 = axis_manip.init_scatt_wavevector_to_Q(k_i[0], k_i[1], k_f[0], k_f[1], cangles.getAzimuthal(1), 0.0, cangles.getPolar(1), 0.0) V2[str(map_so.id)] = {} V2[str(map_so.id)]["x"] = Q2[X] V2[str(map_so.id)]["y"] = Q2[Y] V2[str(map_so.id)]["z"] = Q2[Z] Q3 = axis_manip.init_scatt_wavevector_to_Q(k_i[0], k_i[1], k_f[0], k_f[1], cangles.getAzimuthal(2), 0.0, cangles.getPolar(2), 0.0) V3[str(map_so.id)] = {} V3[str(map_so.id)]["x"] = Q3[X] V3[str(map_so.id)]["y"] = Q3[Y] V3[str(map_so.id)]["z"] = Q3[Z] Q4 = axis_manip.init_scatt_wavevector_to_Q(k_i[0], k_i[1], k_f[0], k_f[1], cangles.getAzimuthal(3), 0.0, cangles.getPolar(3), 0.0) V4[str(map_so.id)] = {} V4[str(map_so.id)]["x"] = Q4[X] V4[str(map_so.id)]["y"] = Q4[Y] V4[str(map_so.id)]["z"] = Q4[Z] if t is not None: t.getTime(msg="After calculating verticies ") # Form the messages if t is not None: t.getTime(False) jobstr = 'MR' + hlr_utils.create_binner_string(conf) + 'JH' num_lines = len(CNT) * len_E linestr = str(num_lines) if output is not None: outdir = os.path.dirname(output) if outdir != '': if outdir.rfind('.') != -1: outdir = "" else: outdir = "" value = str(som.attr_list["data-run_number"].getValue()).split('/') topdir = os.path.join(outdir, value[0].strip() + "-mesh") try: os.mkdir(topdir) except OSError: pass outtag = os.path.basename(output) if outtag.rfind('.') == -1: outtag = "" else: outtag = outtag.split('.')[0] if outtag != "": filehead = outtag + "_bmesh" if make_fixed: filehead1 = outtag + "_fgrid" filehead2 = outtag + "_conf" else: filehead = "bmesh" if make_fixed: filehead1 = "fgrid" filehead2 = "conf" hfile = open(os.path.join(topdir, "%s.in" % filehead2), "w") print >> hfile, jobstr print >> hfile, linestr hfile.close() import utils use_zero_supp = not conf.no_zero_supp for k in xrange(len_E): ofile = open(os.path.join(topdir, "%s%04d.in" % (filehead, k)), "w") if make_fixed: ofile1 = open(os.path.join(topdir, "%s%04d.in" % (filehead1, k)), "w") for pid in CNT: if use_zero_supp: write_value = not utils.compare(CNT[pid][k], 0.0) == 0 else: write_value = True if write_value: result = [] result.append(str(k)) result.append(str(E_t[k])) result.append(str(E_t[k + 1])) result.append(str(CNT[pid][k])) result.append(str(ERR2[pid][k])) __get_coords(V1, pid, k, result) __get_coords(V2, pid, k, result) __get_coords(V3, pid, k, result) __get_coords(V4, pid, k, result) __get_coords(V1, pid, k + 1, result) __get_coords(V2, pid, k + 1, result) __get_coords(V3, pid, k + 1, result) __get_coords(V4, pid, k + 1, result) print >> ofile, " ".join(result) if make_fixed: result1 = [] result1.append(str(k)) result1.append(str(E_t[k])) result1.append(str(E_t[k + 1])) result1.append(str(CNT[pid][k])) result1.append(str(ERR2[pid][k])) result1.extend([str(x) for x in fixed_grid[pid]]) print >> ofile1, " ".join(result1) ofile.close() if make_fixed: ofile1.close() if t is not None: t.getTime(msg="After creating messages ")
def create_E_vs_Q_dgs(som, E_i, Q_final, **kwargs): """ This function starts with the rebinned energy transfer and turns this into a 2D spectra with E and Q axes for DGS instruments. @param som: The input object with initial IGS wavelength axis @type som: C{SOM.SOM} @param E_i: The initial energy for the given data. @type E_i: C{tuple} @param Q_final: The momentum transfer axis to rebin the data to @type Q_final: C{nessi_list.NessiList} @param kwargs: A list of keyword arguments that the function accepts: @keyword corner_angles: The object that contains the corner geometry information. @type corner_angles: C{dict} @keyword so_id: The identifier represents a number, string, tuple or other object that describes the resulting C{SO} @type so_id: C{int}, C{string}, C{tuple}, C{pixel ID} @keyword y_label: The y axis label @type y_label: C{string} @keyword y_units: The y axis units @type y_units: C{string} @keyword x_labels: This is a list of names that sets the individual x axis labels @type x_labels: C{list} of C{string}s @keyword x_units: This is a list of names that sets the individual x axis units @type x_units: C{list} of C{string}s @keyword split: This flag causes the counts and the fractional area to be written out into separate files. @type split: C{boolean} @keyword configure: This is the object containing the driver configuration. @type configure: C{Configure} @return: Object containing a 2D C{SO} with E and Q axes @rtype: C{SOM.SOM} """ import array_manip import axis_manip import common_lib import hlr_utils import nessi_list import SOM import utils # Check for keywords corner_angles = kwargs["corner_angles"] configure = kwargs.get("configure") split = kwargs.get("split", False) # Setup output object so_dim = SOM.SO(2) so_dim.axis[0].val = Q_final so_dim.axis[1].val = som[0].axis[0].val # E_t # Calculate total 2D array size N_tot = (len(so_dim.axis[0].val) - 1) * (len(so_dim.axis[1].val) - 1) # Create y and var_y lists from total 2D size so_dim.y = nessi_list.NessiList(N_tot) so_dim.var_y = nessi_list.NessiList(N_tot) # Create area sum and errors for the area sum lists from total 2D size area_sum = nessi_list.NessiList(N_tot) area_sum_err2 = nessi_list.NessiList(N_tot) # Convert initial energy to initial wavevector l_i = common_lib.energy_to_wavelength(E_i) k_i = common_lib.wavelength_to_scalar_k(l_i) # Since all the data is rebinned to the same energy transfer axis, we can # calculate the final energy axis once E_t = som[0].axis[0].val if som[0].axis[0].var is not None: E_t_err2 = som[0].axis[0].var else: E_t_err2 = nessi_list.NessiList(len(E_t)) # Get the bin width arrays from E_t (E_t_bw, E_t_bw_err2) = utils.calc_bin_widths(E_t) E_f = array_manip.sub_ncerr(E_i[0], E_i[1], E_t, E_t_err2) # Now we can get the final wavevector l_f = axis_manip.energy_to_wavelength(E_f[0], E_f[1]) k_f = axis_manip.wavelength_to_scalar_k(l_f[0], l_f[1]) # Output position for Q X = 0 # Iterate though the data len_som = hlr_utils.get_length(som) for i in xrange(len_som): map_so = hlr_utils.get_map_so(som, None, i) yval = hlr_utils.get_value(som, i, "SOM", "y") yerr2 = hlr_utils.get_err2(som, i, "SOM", "y") cangles = corner_angles[str(map_so.id)] avg_theta1 = (cangles.getPolar(0) + cangles.getPolar(1)) / 2.0 avg_theta2 = (cangles.getPolar(2) + cangles.getPolar(3)) / 2.0 Q1 = axis_manip.init_scatt_wavevector_to_scalar_Q(k_i[0], k_i[1], k_f[0][:-1], k_f[1][:-1], avg_theta2, 0.0) Q2 = axis_manip.init_scatt_wavevector_to_scalar_Q(k_i[0], k_i[1], k_f[0][:-1], k_f[1][:-1], avg_theta1, 0.0) Q3 = axis_manip.init_scatt_wavevector_to_scalar_Q(k_i[0], k_i[1], k_f[0][1:], k_f[1][1:], avg_theta1, 0.0) Q4 = axis_manip.init_scatt_wavevector_to_scalar_Q(k_i[0], k_i[1], k_f[0][1:], k_f[1][1:], avg_theta2, 0.0) # Calculate the area of the E,Q polygons (A, A_err2) = utils.calc_eq_jacobian_dgs(E_t[:-1], E_t[:-1], E_t[1:], E_t[1:], Q1[X], Q2[X], Q3[X], Q4[X]) # Apply the Jacobian: C/dE_t * dE_t / A(EQ) = C/A(EQ) (jac_ratio, jac_ratio_err2) = array_manip.div_ncerr(E_t_bw, E_t_bw_err2, A, A_err2) (counts, counts_err2) = array_manip.mult_ncerr(yval, yerr2, jac_ratio, jac_ratio_err2) try: (y_2d, y_2d_err2, area_new, bin_count) = axis_manip.rebin_2D_quad_to_rectlin(Q1[X], E_t[:-1], Q2[X], E_t[:-1], Q3[X], E_t[1:], Q4[X], E_t[1:], counts, counts_err2, so_dim.axis[0].val, so_dim.axis[1].val) del bin_count except IndexError, e: # Get the offending index from the error message index = int(str(e).split()[1].split('index')[-1].strip('[]')) print "Id:", map_so.id print "Index:", index print "Verticies: %f, %f, %f, %f, %f, %f, %f, %f" % (Q1[X][index], E_t[:-1][index], Q2[X][index], E_t[:-1][index], Q3[X][index], E_t[1:][index], Q4[X][index], E_t[1:][index]) raise IndexError(str(e)) # Add in together with previous results (so_dim.y, so_dim.var_y) = array_manip.add_ncerr(so_dim.y, so_dim.var_y, y_2d, y_2d_err2) (area_sum, area_sum_err2) = array_manip.add_ncerr(area_sum, area_sum_err2, area_new, area_sum_err2)
def create_E_vs_Q_igs(som, *args, **kwargs): """ This function starts with the initial IGS wavelength axis and turns this into a 2D spectra with E and Q axes. @param som: The input object with initial IGS wavelength axis @type som: C{SOM.SOM} @param args: A mandatory list of axes for rebinning. There is a particular order to them. They should be present in the following order: Without errors 1. Energy transfer 2. Momentum transfer With errors 1. Energy transfer 2. Energy transfer error^2 3. Momentum transfer 4. Momentum transfer error ^2 @type args: C{nessi_list.NessiList}s @param kwargs: A list of keyword arguments that the function accepts: @keyword withXVar: Flag for whether the function should be expecting the associated axes to have errors. The default value will be I{False}. @type withXVar: C{boolean} @keyword data_type: Name of the data type which can be either I{histogram}, I{density} or I{coordinate}. The default value will be I{histogram} @type data_type: C{string} @keyword Q_filter: Flag to turn on or off Q filtering. The default behavior is I{True}. @type Q_filter: C{boolean} @keyword so_id: The identifier represents a number, string, tuple or other object that describes the resulting C{SO} @type so_id: C{int}, C{string}, C{tuple}, C{pixel ID} @keyword y_label: The y axis label @type y_label: C{string} @keyword y_units: The y axis units @type y_units: C{string} @keyword x_labels: This is a list of names that sets the individual x axis labels @type x_labels: C{list} of C{string}s @keyword x_units: This is a list of names that sets the individual x axis units @type x_units: C{list} of C{string}s @keyword split: This flag causes the counts and the fractional area to be written out into separate files. @type split: C{boolean} @keyword configure: This is the object containing the driver configuration. @type configure: C{Configure} @return: Object containing a 2D C{SO} with E and Q axes @rtype: C{SOM.SOM} @raise RuntimeError: Anything other than a C{SOM} is passed to the function @raise RuntimeError: An instrument is not contained in the C{SOM} """ import nessi_list # Setup some variables dim = 2 N_y = [] N_tot = 1 N_args = len(args) # Get T0 slope in order to calculate dT = dT_i + dT_0 try: t_0_slope = som.attr_list["Time_zero_slope"][0] t_0_slope_err2 = som.attr_list["Time_zero_slope"][1] except KeyError: t_0_slope = float(0.0) t_0_slope_err2 = float(0.0) # Check withXVar keyword argument and also check number of given args. # Set xvar to the appropriate value try: value = kwargs["withXVar"] if value.lower() == "true": if N_args != 4: raise RuntimeError("Since you have requested x errors, 4 x "\ +"axes must be provided.") else: xvar = True elif value.lower() == "false": if N_args != 2: raise RuntimeError("Since you did not requested x errors, 2 "\ +"x axes must be provided.") else: xvar = False else: raise RuntimeError("Do not understand given parameter %s" % \ value) except KeyError: if N_args != 2: raise RuntimeError("Since you did not requested x errors, 2 "\ +"x axes must be provided.") else: xvar = False # Check dataType keyword argument. An offset will be set to 1 for the # histogram type and 0 for either density or coordinate try: data_type = kwargs["data_type"] if data_type.lower() == "histogram": offset = 1 elif data_type.lower() == "density" or \ data_type.lower() == "coordinate": offset = 0 else: raise RuntimeError("Do not understand data type given: %s" % \ data_type) # Default is offset for histogram except KeyError: offset = 1 try: Q_filter = kwargs["Q_filter"] except KeyError: Q_filter = True # Check for split keyword try: split = kwargs["split"] except KeyError: split = False # Check for configure keyword try: configure = kwargs["configure"] except KeyError: configure = None so_dim = SOM.SO(dim) for i in range(dim): # Set the x-axis arguments from the *args list into the new SO if not xvar: # Axis positions are 1 (Q) and 0 (E) position = dim - i - 1 so_dim.axis[i].val = args[position] else: # Axis positions are 2 (Q), 3 (eQ), 0 (E), 1 (eE) position = dim - 2 * i so_dim.axis[i].val = args[position] so_dim.axis[i].var = args[position + 1] # Set individual value axis sizes (not x-axis size) N_y.append(len(args[position]) - offset) # Calculate total 2D array size N_tot = N_tot * N_y[-1] # Create y and var_y lists from total 2D size so_dim.y = nessi_list.NessiList(N_tot) so_dim.var_y = nessi_list.NessiList(N_tot) # Create area sum and errors for the area sum lists from total 2D size area_sum = nessi_list.NessiList(N_tot) area_sum_err2 = nessi_list.NessiList(N_tot) # Create area sum and errors for the area sum lists from total 2D size bin_count = nessi_list.NessiList(N_tot) bin_count_err2 = nessi_list.NessiList(N_tot) inst = som.attr_list.instrument lambda_final = som.attr_list["Wavelength_final"] inst_name = inst.get_name() import bisect import math import dr_lib import utils arr_len = 0 #: Vector of zeros for function calculations zero_vec = None for j in xrange(hlr_utils.get_length(som)): # Get counts counts = hlr_utils.get_value(som, j, "SOM", "y") counts_err2 = hlr_utils.get_err2(som, j, "SOM", "y") arr_len = len(counts) zero_vec = nessi_list.NessiList(arr_len) # Get mapping SO map_so = hlr_utils.get_map_so(som, None, j) # Get lambda_i l_i = hlr_utils.get_value(som, j, "SOM", "x") l_i_err2 = hlr_utils.get_err2(som, j, "SOM", "x") # Get lambda_f from instrument information l_f_tuple = hlr_utils.get_special(lambda_final, map_so) l_f = l_f_tuple[0] l_f_err2 = l_f_tuple[1] # Get source to sample distance (L_s, L_s_err2) = hlr_utils.get_parameter("primary", map_so, inst) # Get sample to detector distance L_d_tuple = hlr_utils.get_parameter("secondary", map_so, inst) L_d = L_d_tuple[0] # Get polar angle from instrument information (angle, angle_err2) = hlr_utils.get_parameter("polar", map_so, inst) # Get the detector pixel height dh_tuple = hlr_utils.get_parameter("dh", map_so, inst) dh = dh_tuple[0] # Need dh in units of Angstrom dh *= 1e10 # Calculate T_i (T_i, T_i_err2) = axis_manip.wavelength_to_tof(l_i, l_i_err2, L_s, L_s_err2) # Scale counts by lambda_f / lambda_i (l_i_bc, l_i_bc_err2) = utils.calc_bin_centers(l_i, l_i_err2) (ratio, ratio_err2) = array_manip.div_ncerr(l_f, l_f_err2, l_i_bc, l_i_bc_err2) (counts, counts_err2) = array_manip.mult_ncerr(counts, counts_err2, ratio, ratio_err2) # Calculate E_i (E_i, E_i_err2) = axis_manip.wavelength_to_energy(l_i, l_i_err2) # Calculate E_f (E_f, E_f_err2) = axis_manip.wavelength_to_energy(l_f, l_f_err2) # Calculate E_t (E_t, E_t_err2) = array_manip.sub_ncerr(E_i, E_i_err2, E_f, E_f_err2) if inst_name == "BSS": # Convert E_t from meV to ueV (E_t, E_t_err2) = array_manip.mult_ncerr(E_t, E_t_err2, 1000.0, 0.0) (counts, counts_err2) = array_manip.mult_ncerr(counts, counts_err2, 1.0 / 1000.0, 0.0) # Convert lambda_i to k_i (k_i, k_i_err2) = axis_manip.wavelength_to_scalar_k(l_i, l_i_err2) # Convert lambda_f to k_f (k_f, k_f_err2) = axis_manip.wavelength_to_scalar_k(l_f, l_f_err2) # Convert k_i and k_f to Q (Q, Q_err2) = axis_manip.init_scatt_wavevector_to_scalar_Q( k_i, k_i_err2, k_f, k_f_err2, angle, angle_err2) # Calculate dT = dT_0 + dT_i dT_i = utils.calc_bin_widths(T_i, T_i_err2) (l_i_bw, l_i_bw_err2) = utils.calc_bin_widths(l_i, l_i_err2) dT_0 = array_manip.mult_ncerr(l_i_bw, l_i_bw_err2, t_0_slope, t_0_slope_err2) dT_tuple = array_manip.add_ncerr(dT_i[0], dT_i[1], dT_0[0], dT_0[1]) dT = dT_tuple[0] # Calculate Jacobian if inst_name == "BSS": (x_1, x_2, x_3, x_4) = dr_lib.calc_BSS_coeffs( map_so, inst, (E_i, E_i_err2), (Q, Q_err2), (k_i, k_i_err2), (T_i, T_i_err2), dh, angle, E_f, k_f, l_f, L_s, L_d, t_0_slope, zero_vec) else: raise RuntimeError("Do not know how to calculate x_i "\ +"coefficients for instrument %s" % inst_name) (A, A_err2) = dr_lib.calc_EQ_Jacobian(x_1, x_2, x_3, x_4, dT, dh, zero_vec) # Apply Jacobian: C/dlam * dlam / A(EQ) = C/EQ (jac_ratio, jac_ratio_err2) = array_manip.div_ncerr(l_i_bw, l_i_bw_err2, A, A_err2) (counts, counts_err2) = array_manip.mult_ncerr(counts, counts_err2, jac_ratio, jac_ratio_err2) # Reverse counts, E_t, k_i and Q E_t = axis_manip.reverse_array_cp(E_t) E_t_err2 = axis_manip.reverse_array_cp(E_t_err2) Q = axis_manip.reverse_array_cp(Q) Q_err2 = axis_manip.reverse_array_cp(Q_err2) counts = axis_manip.reverse_array_cp(counts) counts_err2 = axis_manip.reverse_array_cp(counts_err2) k_i = axis_manip.reverse_array_cp(k_i) x_1 = axis_manip.reverse_array_cp(x_1) x_2 = axis_manip.reverse_array_cp(x_2) x_3 = axis_manip.reverse_array_cp(x_3) x_4 = axis_manip.reverse_array_cp(x_4) dT = axis_manip.reverse_array_cp(dT) # Filter for duplicate Q values if Q_filter: k_i_cutoff = k_f * math.cos(angle) k_i_cutbin = bisect.bisect(k_i, k_i_cutoff) counts.__delslice__(0, k_i_cutbin) counts_err2.__delslice__(0, k_i_cutbin) Q.__delslice__(0, k_i_cutbin) Q_err2.__delslice__(0, k_i_cutbin) E_t.__delslice__(0, k_i_cutbin) E_t_err2.__delslice__(0, k_i_cutbin) x_1.__delslice__(0, k_i_cutbin) x_2.__delslice__(0, k_i_cutbin) x_3.__delslice__(0, k_i_cutbin) x_4.__delslice__(0, k_i_cutbin) dT.__delslice__(0, k_i_cutbin) zero_vec.__delslice__(0, k_i_cutbin) try: if inst_name == "BSS": ((Q_1, E_t_1), (Q_2, E_t_2), (Q_3, E_t_3), (Q_4, E_t_4)) = dr_lib.calc_BSS_EQ_verticies( (E_t, E_t_err2), (Q, Q_err2), x_1, x_2, x_3, x_4, dT, dh, zero_vec) else: raise RuntimeError("Do not know how to calculate (Q_i, "\ +"E_t_i) verticies for instrument %s" \ % inst_name) except IndexError: # All the data got Q filtered, move on continue try: (y_2d, y_2d_err2, area_new, bin_count_new) = axis_manip.rebin_2D_quad_to_rectlin( Q_1, E_t_1, Q_2, E_t_2, Q_3, E_t_3, Q_4, E_t_4, counts, counts_err2, so_dim.axis[0].val, so_dim.axis[1].val) except IndexError, e: # Get the offending index from the error message index = int(str(e).split()[1].split('index')[-1].strip('[]')) print "Id:", map_so.id print "Index:", index print "Verticies: %f, %f, %f, %f, %f, %f, %f, %f" % ( Q_1[index], E_t_1[index], Q_2[index], E_t_2[index], Q_3[index], E_t_3[index], Q_4[index], E_t_4[index]) raise IndexError(str(e)) # Add in together with previous results (so_dim.y, so_dim.var_y) = array_manip.add_ncerr(so_dim.y, so_dim.var_y, y_2d, y_2d_err2) (area_sum, area_sum_err2) = array_manip.add_ncerr(area_sum, area_sum_err2, area_new, area_sum_err2) if configure.dump_pix_contrib or configure.scale_sqe: if inst_name == "BSS": dOmega = dr_lib.calc_BSS_solid_angle(map_so, inst) (bin_count_new, bin_count_err2) = array_manip.mult_ncerr( bin_count_new, bin_count_err2, dOmega, 0.0) (bin_count, bin_count_err2) = array_manip.add_ncerr( bin_count, bin_count_err2, bin_count_new, bin_count_err2) else: del bin_count_new
def create_E_vs_Q_dgs(som, E_i, Q_final, **kwargs): """ This function starts with the rebinned energy transfer and turns this into a 2D spectra with E and Q axes for DGS instruments. @param som: The input object with initial IGS wavelength axis @type som: C{SOM.SOM} @param E_i: The initial energy for the given data. @type E_i: C{tuple} @param Q_final: The momentum transfer axis to rebin the data to @type Q_final: C{nessi_list.NessiList} @param kwargs: A list of keyword arguments that the function accepts: @keyword corner_angles: The object that contains the corner geometry information. @type corner_angles: C{dict} @keyword so_id: The identifier represents a number, string, tuple or other object that describes the resulting C{SO} @type so_id: C{int}, C{string}, C{tuple}, C{pixel ID} @keyword y_label: The y axis label @type y_label: C{string} @keyword y_units: The y axis units @type y_units: C{string} @keyword x_labels: This is a list of names that sets the individual x axis labels @type x_labels: C{list} of C{string}s @keyword x_units: This is a list of names that sets the individual x axis units @type x_units: C{list} of C{string}s @keyword split: This flag causes the counts and the fractional area to be written out into separate files. @type split: C{boolean} @keyword configure: This is the object containing the driver configuration. @type configure: C{Configure} @return: Object containing a 2D C{SO} with E and Q axes @rtype: C{SOM.SOM} """ import array_manip import axis_manip import common_lib import hlr_utils import nessi_list import SOM import utils # Check for keywords corner_angles = kwargs["corner_angles"] configure = kwargs.get("configure") split = kwargs.get("split", False) # Setup output object so_dim = SOM.SO(2) so_dim.axis[0].val = Q_final so_dim.axis[1].val = som[0].axis[0].val # E_t # Calculate total 2D array size N_tot = (len(so_dim.axis[0].val) - 1) * (len(so_dim.axis[1].val) - 1) # Create y and var_y lists from total 2D size so_dim.y = nessi_list.NessiList(N_tot) so_dim.var_y = nessi_list.NessiList(N_tot) # Create area sum and errors for the area sum lists from total 2D size area_sum = nessi_list.NessiList(N_tot) area_sum_err2 = nessi_list.NessiList(N_tot) # Convert initial energy to initial wavevector l_i = common_lib.energy_to_wavelength(E_i) k_i = common_lib.wavelength_to_scalar_k(l_i) # Since all the data is rebinned to the same energy transfer axis, we can # calculate the final energy axis once E_t = som[0].axis[0].val if som[0].axis[0].var is not None: E_t_err2 = som[0].axis[0].var else: E_t_err2 = nessi_list.NessiList(len(E_t)) # Get the bin width arrays from E_t (E_t_bw, E_t_bw_err2) = utils.calc_bin_widths(E_t) E_f = array_manip.sub_ncerr(E_i[0], E_i[1], E_t, E_t_err2) # Now we can get the final wavevector l_f = axis_manip.energy_to_wavelength(E_f[0], E_f[1]) k_f = axis_manip.wavelength_to_scalar_k(l_f[0], l_f[1]) # Output position for Q X = 0 # Iterate though the data len_som = hlr_utils.get_length(som) for i in xrange(len_som): map_so = hlr_utils.get_map_so(som, None, i) yval = hlr_utils.get_value(som, i, "SOM", "y") yerr2 = hlr_utils.get_err2(som, i, "SOM", "y") cangles = corner_angles[str(map_so.id)] avg_theta1 = (cangles.getPolar(0) + cangles.getPolar(1)) / 2.0 avg_theta2 = (cangles.getPolar(2) + cangles.getPolar(3)) / 2.0 Q1 = axis_manip.init_scatt_wavevector_to_scalar_Q( k_i[0], k_i[1], k_f[0][:-1], k_f[1][:-1], avg_theta2, 0.0) Q2 = axis_manip.init_scatt_wavevector_to_scalar_Q( k_i[0], k_i[1], k_f[0][:-1], k_f[1][:-1], avg_theta1, 0.0) Q3 = axis_manip.init_scatt_wavevector_to_scalar_Q( k_i[0], k_i[1], k_f[0][1:], k_f[1][1:], avg_theta1, 0.0) Q4 = axis_manip.init_scatt_wavevector_to_scalar_Q( k_i[0], k_i[1], k_f[0][1:], k_f[1][1:], avg_theta2, 0.0) # Calculate the area of the E,Q polygons (A, A_err2) = utils.calc_eq_jacobian_dgs(E_t[:-1], E_t[:-1], E_t[1:], E_t[1:], Q1[X], Q2[X], Q3[X], Q4[X]) # Apply the Jacobian: C/dE_t * dE_t / A(EQ) = C/A(EQ) (jac_ratio, jac_ratio_err2) = array_manip.div_ncerr(E_t_bw, E_t_bw_err2, A, A_err2) (counts, counts_err2) = array_manip.mult_ncerr(yval, yerr2, jac_ratio, jac_ratio_err2) try: (y_2d, y_2d_err2, area_new, bin_count) = axis_manip.rebin_2D_quad_to_rectlin( Q1[X], E_t[:-1], Q2[X], E_t[:-1], Q3[X], E_t[1:], Q4[X], E_t[1:], counts, counts_err2, so_dim.axis[0].val, so_dim.axis[1].val) del bin_count except IndexError, e: # Get the offending index from the error message index = int(str(e).split()[1].split('index')[-1].strip('[]')) print "Id:", map_so.id print "Index:", index print "Verticies: %f, %f, %f, %f, %f, %f, %f, %f" % ( Q1[X][index], E_t[:-1][index], Q2[X][index], E_t[:-1][index], Q3[X][index], E_t[1:][index], Q4[X][index], E_t[1:][index]) raise IndexError(str(e)) # Add in together with previous results (so_dim.y, so_dim.var_y) = array_manip.add_ncerr(so_dim.y, so_dim.var_y, y_2d, y_2d_err2) (area_sum, area_sum_err2) = array_manip.add_ncerr(area_sum, area_sum_err2, area_new, area_sum_err2)
def create_Qvec_vs_E_dgs(som, E_i, conf, **kwargs): """ This function starts with the energy transfer axis from DGS reduction and turns this into a 4D spectra with Qx, Qy, Qz and Et axes. @param som: The input object with initial IGS wavelength axis @type som: C{SOM.SOM} @param E_i: The initial energy for the given data. @type E_i: C{tuple} @param conf: Object that contains the current setup of the driver. @type conf: L{hlr_utils.Configure} @param kwargs: A list of keyword arguments that the function accepts: @keyword timer: Timing object so the function can perform timing estimates. @type timer: C{sns_timer.DiffTime} @keyword corner_angles: The object that contains the corner geometry information. @type corner_angles: C{dict} @keyword make_fixed: A flag that turns on writing the fixed grid mesh information to a file. @type make_fixed: C{boolean} @keyword output: The output filename and or directory. @type output: C{string} """ import array_manip import axis_manip import common_lib import hlr_utils import os # Check keywords try: t = kwargs["timer"] except KeyError: t = None corner_angles = kwargs["corner_angles"] try: make_fixed = kwargs["make_fixed"] except KeyError: make_fixed = False try: output = kwargs["output"] except KeyError: output = None # Convert initial energy to initial wavevector l_i = common_lib.energy_to_wavelength(E_i) k_i = common_lib.wavelength_to_scalar_k(l_i) # Since all the data is rebinned to the same energy transfer axis, we can # calculate the final energy axis once E_t = som[0].axis[0].val if som[0].axis[0].var is not None: E_t_err2 = som[0].axis[0].var else: import nessi_list E_t_err2 = nessi_list.NessiList(len(E_t)) E_f = array_manip.sub_ncerr(E_i[0], E_i[1], E_t, E_t_err2) # Check for negative final energies which will cause problems with # wavelength conversion due to square root if E_f[0][-1] < 0: E_f[0].reverse() E_f[1].reverse() index = 0 for E in E_f[0]: if E >= 0: break index += 1 E_f[0].__delslice__(0, index) E_f[1].__delslice__(0, index) E_f[0].reverse() E_f[1].reverse() len_E = len(E_f[0]) - 1 # Now we can get the final wavevector l_f = axis_manip.energy_to_wavelength(E_f[0], E_f[1]) k_f = axis_manip.wavelength_to_scalar_k(l_f[0], l_f[1]) # Grab the instrument from the som inst = som.attr_list.instrument if make_fixed: import SOM fixed_grid = {} for key in corner_angles: so_id = SOM.NeXusId.fromString(key).toTuple() try: pathlength = inst.get_secondary(so_id)[0] points = [] for j in range(4): points.extend(__calc_xyz(pathlength, corner_angles[key].getPolar(j), corner_angles[key].getAzimuthal(j))) fixed_grid[key] = points except KeyError: # Pixel ID is not in instrument geometry pass CNT = {} ERR2 = {} V1 = {} V2 = {} V3 = {} V4 = {} # Output positions for Qx, Qy, Qz coordinates X = 0 Y = 2 Z = 4 if t is not None: t.getTime(False) # Iterate though the data len_som = hlr_utils.get_length(som) for i in xrange(len_som): map_so = hlr_utils.get_map_so(som, None, i) yval = hlr_utils.get_value(som, i, "SOM", "y") yerr2 = hlr_utils.get_err2(som, i, "SOM", "y") CNT[str(map_so.id)] = yval ERR2[str(map_so.id)] = yerr2 cangles = corner_angles[str(map_so.id)] Q1 = axis_manip.init_scatt_wavevector_to_Q(k_i[0], k_i[1], k_f[0], k_f[1], cangles.getAzimuthal(0), 0.0, cangles.getPolar(0), 0.0) V1[str(map_so.id)] = {} V1[str(map_so.id)]["x"] = Q1[X] V1[str(map_so.id)]["y"] = Q1[Y] V1[str(map_so.id)]["z"] = Q1[Z] Q2 = axis_manip.init_scatt_wavevector_to_Q(k_i[0], k_i[1], k_f[0], k_f[1], cangles.getAzimuthal(1), 0.0, cangles.getPolar(1), 0.0) V2[str(map_so.id)] = {} V2[str(map_so.id)]["x"] = Q2[X] V2[str(map_so.id)]["y"] = Q2[Y] V2[str(map_so.id)]["z"] = Q2[Z] Q3 = axis_manip.init_scatt_wavevector_to_Q(k_i[0], k_i[1], k_f[0], k_f[1], cangles.getAzimuthal(2), 0.0, cangles.getPolar(2), 0.0) V3[str(map_so.id)] = {} V3[str(map_so.id)]["x"] = Q3[X] V3[str(map_so.id)]["y"] = Q3[Y] V3[str(map_so.id)]["z"] = Q3[Z] Q4 = axis_manip.init_scatt_wavevector_to_Q(k_i[0], k_i[1], k_f[0], k_f[1], cangles.getAzimuthal(3), 0.0, cangles.getPolar(3), 0.0) V4[str(map_so.id)] = {} V4[str(map_so.id)]["x"] = Q4[X] V4[str(map_so.id)]["y"] = Q4[Y] V4[str(map_so.id)]["z"] = Q4[Z] if t is not None: t.getTime(msg="After calculating verticies ") # Form the messages if t is not None: t.getTime(False) jobstr = 'MR' + hlr_utils.create_binner_string(conf) + 'JH' num_lines = len(CNT) * len_E linestr = str(num_lines) if output is not None: outdir = os.path.dirname(output) if outdir != '': if outdir.rfind('.') != -1: outdir = "" else: outdir = "" value = str(som.attr_list["data-run_number"].getValue()).split('/') topdir = os.path.join(outdir, value[0].strip() + "-mesh") try: os.mkdir(topdir) except OSError: pass outtag = os.path.basename(output) if outtag.rfind('.') == -1: outtag = "" else: outtag = outtag.split('.')[0] if outtag != "": filehead = outtag + "_bmesh" if make_fixed: filehead1 = outtag + "_fgrid" filehead2 = outtag + "_conf" else: filehead = "bmesh" if make_fixed: filehead1 = "fgrid" filehead2 = "conf" hfile = open(os.path.join(topdir, "%s.in" % filehead2), "w") print >> hfile, jobstr print >> hfile, linestr hfile.close() import utils use_zero_supp = not conf.no_zero_supp for k in xrange(len_E): ofile = open(os.path.join(topdir, "%s%04d.in" % (filehead, k)), "w") if make_fixed: ofile1 = open(os.path.join(topdir, "%s%04d.in" % (filehead1, k)), "w") for pid in CNT: if use_zero_supp: write_value = not utils.compare(CNT[pid][k], 0.0) == 0 else: write_value = True if write_value: result = [] result.append(str(k)) result.append(str(E_t[k])) result.append(str(E_t[k+1])) result.append(str(CNT[pid][k])) result.append(str(ERR2[pid][k])) __get_coords(V1, pid, k, result) __get_coords(V2, pid, k, result) __get_coords(V3, pid, k, result) __get_coords(V4, pid, k, result) __get_coords(V1, pid, k+1, result) __get_coords(V2, pid, k+1, result) __get_coords(V3, pid, k+1, result) __get_coords(V4, pid, k+1, result) print >> ofile, " ".join(result) if make_fixed: result1 = [] result1.append(str(k)) result1.append(str(E_t[k])) result1.append(str(E_t[k+1])) result1.append(str(CNT[pid][k])) result1.append(str(ERR2[pid][k])) result1.extend([str(x) for x in fixed_grid[pid]]) print >> ofile1, " ".join(result1) ofile.close() if make_fixed: ofile1.close() if t is not None: t.getTime(msg="After creating messages ")