def thetaTwothetaToQxQz(data, output_grid, wavelength=5.0, qxmin=-0.003, qxmax=0.003, qxbins=101, qzmin=0.0001, qzmax=0.1, qzbins=101): """ Figures out the Qx, Qz values of each datapoint and throws them in the correct bin. If no grid is specified, one is created that covers the whole range of Q in the dataset If autofill_gaps is True, does reverse lookup to plug holes in the output (but pixel count is still zero for these bins) **Inputs** data (ospec2d): input data output_grid (ospec2d): empty data object with axes defined (optional) wavelength (float): override wavelength in data file qxmin (float): lower bound of Qx range in rebinning qxmax (float): upper bound of Qx range in rebinning qxbins (int): number of bins to subdivide the range between qxmin and qxmax qzmin (float): lower bound of Qz range in rebinning qzmax (float): upper bound of Qz range in rebinning qzbins (int): number of bins to subdivide the range between qzmin and qzmax **Returns** output (ospec2d): output data rebinned into Qx, Qz 2016-04-01 Brian Maranville """ print "output grid: ", output_grid if output_grid == None: info = [{"name": "qx", "units": "inv. Angstroms", "values": linspace(qxmin, qxmax, qxbins) }, {"name": "qz", "units": "inv. Angstroms", "values": linspace(qzmin, qzmax, qzbins) },] old_info = data.infoCopy() info.append(old_info[2]) # column information! info.append(old_info[3]) # creation story! output_grid = MetaArray(zeros((qxbins, qzbins, data.shape[-1])), info=info) else: outgrid_info = deepcopy(output_grid._info) # take axes and creation story from emptyqxqz... outgrid_info[2] = deepcopy(data._info[2]) # take column number and names from dataset output_grid = MetaArray(zeros((output_grid.shape[0], output_grid.shape[1], data.shape[2])), info=outgrid_info) theta_axis = data._getAxis('theta') twotheta_axis = data._getAxis('twotheta') qLength = 2.0 * pi / wavelength th_array = data.axisValues('theta').copy() twotheta_array = data.axisValues('twotheta').copy() if theta_axis < twotheta_axis: # then theta is first: add a dimension at the end th_array.shape = th_array.shape + (1,) twotheta_array.shape = (1,) + twotheta_array.shape else: twotheta_array.shape = twotheta_array.shape + (1,) th_array.shape = (1,) + th_array.shape tilt_array = th_array - (twotheta_array / 2.0) qxOut = 2.0 * qLength * sin((pi / 180.0) * (twotheta_array / 2.0)) * sin(pi * tilt_array / 180.0) qzOut = 2.0 * qLength * sin((pi / 180.0) * (twotheta_array / 2.0)) * cos(pi * tilt_array / 180.0) # getting values from output grid: outgrid_info = output_grid.infoCopy() numcols = len(outgrid_info[2]['cols']) qx_array = output_grid.axisValues('qx') dqx = qx_array[1] - qx_array[0] qz_array = output_grid.axisValues('qz') dqz = qz_array[1] - qz_array[0] #framed_array = zeros((qz_array.shape[0] + 2, qx_array.shape[0] + 2, numcols)) target_qx = ((qxOut - qx_array[0]) / dqx).astype(int) #return target_qx, qxOut target_qz = ((qzOut - qz_array[0]) / dqz).astype(int) target_mask = (target_qx >= 0) * (target_qx < qx_array.shape[0]) target_mask *= (target_qz >= 0) * (target_qz < qz_array.shape[0]) target_qx_list = target_qx[target_mask] target_qz_list = target_qz[target_mask] for i, col in enumerate(outgrid_info[2]['cols']): values_to_bin = data[:,:,col['name']].view(ndarray)[target_mask] outshape = (output_grid.shape[0], output_grid.shape[1]) hist2d, xedges, yedges = histogram2d(target_qx_list,target_qz_list, \ bins = (outshape[0],outshape[1]), range=((0,outshape[0]),(0,outshape[1])), weights=values_to_bin) output_grid[:,:,col['name']] += hist2d #framed_array[target_qz_list, target_qx_list, i] = data[:,:,col['name']][target_mask] cols = outgrid_info[2]['cols'] data_cols = [col['name'] for col in cols if col['name'].startswith('counts')] monitor_cols = [col['name'] for col in cols if col['name'].startswith('monitor')] # just take the first one... if len(monitor_cols) > 0: monitor_col = monitor_cols[0] data_missing_mask = (output_grid[:,:,monitor_col] == 0) for dc in data_cols: output_grid[:,:,dc].view(ndarray)[data_missing_mask] = NaN; #extra_info output_grid._info[-1] = data._info[-1].copy() print "output shape:", output_grid.shape return output_grid
def thetaTwothetaToAlphaIAlphaF(data): """ Figures out the angle in, angle out values of each datapoint and throws them in the correct bin. If no grid is specified, one is created that covers the whole range of the dataset **Inputs** data (ospec2d): input data **Returns** output (ospec2d): output data rebinned into alpha_i, alpha_f 2016-04-01 Brian Maranville """ theta_axis = data._getAxis('theta') twotheta_axis = data._getAxis('twotheta') th_array = data.axisValues('theta').copy() twotheta_array = data.axisValues('twotheta').copy() two_theta_step = twotheta_array[1] - twotheta_array[0] theta_step = th_array[1] - th_array[0] af_max = (twotheta_array.max() - th_array.min()) af_min = (twotheta_array.min() - th_array.max()) alpha_i = th_array.copy() alpha_f = arange(af_min, af_max, two_theta_step) info = [{"name": "alpha_i", "units": "degrees", "values": th_array.copy() }, {"name": "alpha_f", "units": "degrees", "values": alpha_f.copy() },] old_info = data.infoCopy() info.append(old_info[2]) # column information! info.append(old_info[3]) # creation story! output_grid = MetaArray(zeros((th_array.shape[0], alpha_f.shape[0], data.shape[-1])), info=info) if theta_axis < twotheta_axis: # then theta is first: add a dimension at the end alpha_i.shape = alpha_i.shape + (1,) ai_out = indices((th_array.shape[0], twotheta_array.shape[0]))[0] twotheta_array.shape = (1,) + twotheta_array.shape else: alpha_i.shape = (1,) + alpha_i.shape ai_out = indices((twotheta_array.shape[0], th_array.shape[0]))[1] twotheta_array.shape = twotheta_array.shape + (1,) af_out = twotheta_array - alpha_i # getting values from output grid: outgrid_info = output_grid.infoCopy() numcols = len(outgrid_info[2]['cols']) #target_ai = ((ai_out - th_array[0]) / theta_step).flatten().astype(int).tolist() target_ai = ai_out.flatten().astype(int).tolist() #return target_qx, qxOut target_af = ((af_out - af_min) / two_theta_step).flatten().astype(int).tolist() for i, col in enumerate(outgrid_info[2]['cols']): values_to_bin = data[:,:,col['name']].view(ndarray).flatten().tolist() print len(target_ai), len(target_af), len(values_to_bin) outshape = (output_grid.shape[0], output_grid.shape[1]) hist2d, xedges, yedges = histogram2d(target_ai, target_af, bins = (outshape[0],outshape[1]), range=((0,outshape[0]),(0,outshape[1])), weights=values_to_bin) output_grid[:,:,col['name']] += hist2d cols = outgrid_info[2]['cols'] data_cols = [col['name'] for col in cols if col['name'].startswith('counts')] monitor_cols = [col['name'] for col in cols if col['name'].startswith('monitor')] # just take the first one... if len(monitor_cols) > 0: monitor_col = monitor_cols[0] data_missing_mask = (output_grid[:,:,monitor_col] == 0) for dc in data_cols: output_grid[:,:,dc].view(ndarray)[data_missing_mask] = NaN; #extra info changed output_grid._info[-1] = data._info[-1].copy() return output_grid
def apply(self, data, theta=None, qxmin=None, qxmax=None, qxbins=None, qzmin=None, qzmax=None, qzbins=None): info = [{"name": "qx", "units": "inv. Angstroms", "values": linspace(qxmin, qxmax, qxbins) }, {"name": "qz", "units": "inv. Angstroms", "values": linspace(qzmin, qzmax, qzbins) },] old_info = data.infoCopy() info.append(old_info[2]) # column information! info.append(old_info[3]) # creation story! output_grid = MetaArray(zeros((qxbins, qzbins, data.shape[-1])), info=info) #if output_grid == None: # output_grid = EmptyQxQzGrid(*self.default_qxqz_gridvals) #else: # output_grid = deepcopy(output_grid) if (theta == "") or (theta == None): if 'state' in data._info[-1]: theta = float(data._info[-1]['state']['A[1]']) print 'theta:', theta else: print "can't run without theta!" return wl_array = data.axisValues('wavelength').copy() wl_array.shape = wl_array.shape + (1,) twotheta_array = data.axisValues('twotheta').copy() twotheta_array.shape = (1,) + twotheta_array.shape qxOut, qzOut = self.getQxQz(theta, twotheta_array, wl_array) # getting values from output grid: outgrid_info = output_grid.infoCopy() numcols = len(outgrid_info[2]['cols']) qx_array = output_grid.axisValues('qx') dqx = qx_array[1] - qx_array[0] qz_array = output_grid.axisValues('qz') dqz = qz_array[1] - qz_array[0] framed_array = zeros((qz_array.shape[0]+2, qx_array.shape[0]+2, numcols)) target_qx = ((qxOut - qx_array[0])/dqx + 1).astype(int) #return target_qx, qxOut target_qz = ((qzOut - qz_array[0])/dqz + 1).astype(int) target_mask = (target_qx >= 0) * (target_qx < qx_array.shape[0]) target_mask *= (target_qz >= 0) * (target_qz < qz_array.shape[0]) target_qx_list = target_qx[target_mask] target_qz_list = target_qz[target_mask] #target_qx = target_qx.clip(0, qx_array.shape[0]+1) #target_qz = target_qz.clip(0, qz_array.shape[0]+1) for i, col in enumerate(outgrid_info[2]['cols']): values_to_bin = data[:,:,col['name']][target_mask] outshape = (output_grid.shape[0], output_grid.shape[1]) hist2d, xedges, yedges = histogram2d(target_qx_list,target_qz_list, bins = (outshape[0],outshape[1]), range=((0,outshape[0]),(0,outshape[1])), weights=values_to_bin) output_grid[:,:,col['name']] += hist2d #framed_array[target_qz_list, target_qx_list, i] = data[:,:,col['name']][target_mask] #trimmed_array = framed_array[1:-1, 1:-1] #output_grid[:,:] = trimmed_array creation_story = data._info[-1]['CreationStory'] new_creation_story = creation_story + ".filter('{0}', {1})".format(self.__class__.__name__, output_grid._info[-1]['CreationStory']) #print new_creation_story output_grid._info[-1] = data._info[-1].copy() output_grid._info[-1]['CreationStory'] = new_creation_story return output_grid