def apply(self, data, pixels_per_degree=80.0, qzero_pixel=309, instr_resolution=1e-6): new_info = data.infoCopy() det_angle = new_info[0].pop('det_angle') # read and get rid of it! th_vector = data.axisValues('theta') th_spacing = th_vector[1] - th_vector[0] pixels = data.axisValues('xpixel') twoth = -1.0 * (pixels - qzero_pixel) / pixels_per_degree twoth_min = det_angle.min() + twoth.min() twoth_max = det_angle.max() + twoth.max() twoth_max_edge = twoth_max + 1.0 / pixels_per_degree dpp = 1.0 / pixels_per_degree output_twoth_bin_edges = arange(twoth_max + dpp, twoth_min - dpp, -dpp) output_twoth = output_twoth_bin_edges[:-1] #input_twoth_bin_edges = output_twoth_bin_edges.copy() #input_twoth_bin_edges[:-1] = twoth th_bin_edges = linspace(th_vector[0], th_vector[-1] + th_spacing, len(th_vector) + 1) new_info[1]['name'] = 'twotheta' # getting rid of pixel units: substitute twoth new_info[1]['values'] = output_twoth new_info[1]['units'] = 'degrees' new_data = MetaArray((len(th_vector), len(output_twoth), data.shape[2]), info=new_info) # create the output data object! # (still has to be filled with correct values) if ((det_angle.max() - det_angle.min()) < instr_resolution): #then the detector is fixed and we can pass a single 2theta vector to rebin2d input_twoth_bin_edges = empty(len(pixels) + 1) input_twoth_bin_edges[0] = twoth_max + 1.0 / pixels_per_degree input_twoth_bin_edges[1:] = twoth + det_angle.min() data_cols = ['counts', 'pixels', 'monitor', 'count_time'] for col in data_cols: array_to_rebin = data[:, :, col].view(ndarray).copy() new_array = reb.rebin2d(th_bin_edges, input_twoth_bin_edges, array_to_rebin, th_bin_edges, output_twoth_bin_edges) new_data[:, :, col] = new_array else: #then the detector is not fixed, and we have to pass in each A4 value at a time to rebin tth_min = twoth.min() tth_max = twoth.max() for i, da in enumerate(det_angle): twoth_min = da + tth_min twoth_max = da + tth_max input_twoth_bin_edges = empty(len(pixels) + 1) input_twoth_bin_edges[0] = twoth_max + 1.0 / pixels_per_degree input_twoth_bin_edges[1:] = twoth + da data_cols = ['counts', 'pixels', 'monitor', 'count_time'] for col in data_cols: array_to_rebin = data[i, :, col].view(ndarray).copy() new_array = reb.rebin(input_twoth_bin_edges, array_to_rebin, output_twoth_bin_edges) new_data[i, :, col] = new_array return new_data
def make_2th_th_map(self): """ makes a composite array that contains all the data objects in a regular theta-2theta grid. For theta, find stepsize in all data sets, then use largest step size as grid spacing. In 2theta, somewhat simpler: use the pixel size as the grid spacing (1/80 deg) """ from reduction import rebin as reb instr_resolution = 0.00001 # difference that is negligible for all motors num_files = len(self.inFileObjects) th_min = zeros(num_files) th_max = zeros(num_files) th_len = zeros(num_files) th_step = zeros(num_files) twoth_min = zeros(num_files) twoth_max = zeros(num_files) twoth_len = zeros(num_files) twoth_step = zeros(num_files) pixel_vector = arange(609.0) intens_correction, pixel_correction = self.correctionFromPixel( pixel_vector) corrected_pixel = pixel_vector + pixel_correction for i in range(num_files): th_min[i] = self.inFileObjects[i].sample.angle_x.min( ) + self.theta_offset th_max[i] = self.inFileObjects[i].sample.angle_x.max( ) + self.theta_offset th_len[i] = self.inFileObjects[i].sample.angle_x.shape[0] A4_vector = self.inFileObjects[i].detector.angle_x twoth_vector = self.getTwoTheta(corrected_pixel, array([A4_vector]).T) twoth_max[i] = twoth_vector.max() twoth_min[i] = twoth_vector.min() if th_len[i] > 1: th_step[i] = float(th_max[i] - th_min[i]) / th_len[i] else: th_step[i] = 0.0 #if twoth_len[i] > 1: #twoth_step[i] = float(twoth_max[i] - twoth_min[i]) / twoth_len[i] #else: #twoth_step[i] = 0.0 # take maximum A3 spacing as grid spacing for theta: th_stepsize = th_step.max() self.th_stepsize = th_stepsize # take the extrema as the limits of our new grid: th_min_min = th_min.min() self.th_min_min = th_min_min th_max_max = th_max.max() self.th_max_max = th_max_max th_steps = int(float(th_max_max - th_min_min) / th_stepsize) self.th_steps = th_steps # take 1/80 deg as grid spacing for 2theta: twoth_stepsize = 1.0 / 80.0 self.twoth_stepsize = twoth_stepsize # take the extrema as the limits of our new grid: twoth_min_min = twoth_min.min() self.twoth_min_min = twoth_min_min twoth_max_max = twoth_max.max() self.twoth_max_max = twoth_max_max twoth_steps = int( round(float(twoth_max_max - twoth_min_min) / twoth_stepsize)) self.twoth_steps = twoth_steps th_twoth_data_extent = (twoth_min_min, twoth_max_max, th_min_min, th_max_max) #th_twoth_data = zeros((th_steps, twoth_steps, 4)) print th_min_min, th_max_max, th_steps print twoth_min_min, twoth_max_max, twoth_steps twoth_bin_edges = (arange(twoth_steps + 1) * twoth_stepsize) + twoth_min_min #self.twoth_bin_edges = twoth_bin_edges th_bin_edges = (arange(th_steps + 1) * th_stepsize) + th_min_min #self.th_bin_edges = th_bin_edges th_2th_array = zeros((th_steps, twoth_steps, 4)) for i in range(num_files): inData = self.inFileObjects[i] #pixel_vector = arange(609.0,0.0,-1.0) pixel_vector = arange(609.) intens_correction, pixel_correction = self.correctionFromPixel( pixel_vector) corrected_pixel = pixel_vector + pixel_correction intens = inData.detector.counts #cut off the last bit of intens_correction (which is larger by one than intens, because #we're making edges intens_correction = intens_correction[:-1] corrected_I = intens / (1.0 + intens_correction) #corrected_I = intens th = inData.sample.angle_x + self.theta_offset # need one more bin edge than data points: th_vector = zeros(len(th) + 1) th_vector[:len(th)] = th # this fails if there's only 1 theta value for the data file th_vector[-1] = th_vector[-2] + (th_vector[-2] - th_vector[-3]) print th_vector th_vector_comp = (arange(th_len[i] + 1.0) * th_step[i]) + th_min[i] print th_vector_comp #self.th_vector = th_vector #th_array = array([th_vector]).T + zeros(shape(intens)) # if the normalization is chosen to be vs. time instead of vs. monitor counts, the change is # made here: if self.normalization == 'time': monitor_vector = inData.monitor.count_time else: # self.normalization = monitor by default monitor_vector = inData.monitor.counts monitor_array = array([monitor_vector]).T + zeros(shape(intens)) pixel_array = ones(shape(intens)) A4_vector = inData.detector.angle_x if ((A4_vector.max() - A4_vector.min()) < instr_resolution): #then the detector is fixed and we can pass a single 2theta vector to rebin2d twoth_vector = self.getTwoTheta(corrected_pixel, A4_vector.min()) #self.twoth_vector = twoth_vector new_data = reb.rebin2d(th_vector, twoth_vector, corrected_I.astype('float64'), th_bin_edges, twoth_bin_edges) #print th_vector.shape, twoth_vector.shape, corrected_I.shape, th_bin_edges.shape, twoth_bin_edges.shape #new_data = reb.rebin2d(twoth_vector,th_vector,intens,twoth_bin_edges,th_bin_edges) #print new_data new_pixelcount = reb.rebin2d(th_vector, twoth_vector, pixel_array.astype('float64'), th_bin_edges, twoth_bin_edges) new_mon = reb.rebin2d(th_vector, twoth_vector, monitor_array.astype('float64'), th_bin_edges, twoth_bin_edges) #new_pixelcount = reb.rebin2d(twoth_vector,th_vector,pixel_array,twoth_bin_edges,th_bin_edges) #new_mon = reb.rebin2d(twoth_vector,th_vector,monitor_array,twoth_bin_edges,th_bin_edges) th_2th_array[:, :, 0] += new_data th_2th_array[:, :, 1] += new_pixelcount th_2th_array[:, :, 2] += new_mon else: #then the detector is not fixed, and we have to pass in each A4 value at a time to rebin for j in range(th_vector.shape[0] - 1): twoth_vector = self.getTwoTheta(corrected_pixel, A4_vector[j]) #print th_vector.shape, twoth_vector.shape, corrected_I.shape, th_bin_edges.shape, twoth_bin_edges.shape new_data = reb.rebin(twoth_vector, corrected_I[j].astype('float64'), twoth_bin_edges) #new_data = reb.rebin2d(twoth_vector,th_vector[j],corrected_I[:,j],twoth_bin_edges,th_bin_edges) new_pixelcount = reb.rebin( twoth_vector, pixel_array[j].astype('float64'), twoth_bin_edges) new_mon = reb.rebin(twoth_vector, monitor_array[j].astype('float64'), twoth_bin_edges) print j th_2th_array[j, :, 0] += new_data th_2th_array[j, :, 1] += new_pixelcount th_2th_array[j, :, 2] += new_mon print('loaded: ' + inData.name) nonzero_pixels = (th_2th_array[:, :, 1] > 0) monitor_total = th_2th_array[:, :, 2][nonzero_pixels] avg = th_2th_array[:, :, 0][nonzero_pixels] / double(monitor_total) th_2th_array[:, :, 3][nonzero_pixels] = avg self.th_2th_array = th_2th_array th2th_params = { 'description': self.inFileObjects[0].description, 'x_max': twoth_min_min, 'x_min': twoth_max_max, 'x_steps': twoth_steps, 'y_max': th_max_max, 'y_min': th_min_min, 'y_steps': th_steps, 'x_units': '$2\\theta ({}^{\circ})$', 'y_units': '$\\theta ({}^{\circ})$' } twoth_th_array = flipud(th_2th_array.swapaxes(0, 1)) # cut off stuff that should really be zero - bad fp stuff twoth_th_array[:, :, 3][twoth_th_array[:, :, 3] < 1e-16] = 0. title = 'dataset ' + str(self.number) + ': th2th_data' self.th2th_data = plottable_2d_data(twoth_th_array, th2th_params, self, title=title) return
def make_2th_th_map(self): """ makes a composite array that contains all the data objects in a regular theta-2theta grid. For theta, find stepsize in all data sets, then use largest step size as grid spacing. In 2theta, somewhat simpler: use the pixel size as the grid spacing (1/80 deg) """ from reduction import rebin as reb instr_resolution = 0.00001 # difference that is negligible for all motors num_files = len( self.inFileObjects ) th_min = zeros(num_files) th_max = zeros(num_files) th_len = zeros(num_files) th_step = zeros(num_files) twoth_min = zeros(num_files) twoth_max = zeros(num_files) twoth_len = zeros(num_files) twoth_step = zeros(num_files) pixel_vector = arange(609.0) intens_correction, pixel_correction = self.correctionFromPixel(pixel_vector) corrected_pixel = pixel_vector + pixel_correction for i in range(num_files): th_min[i] = self.inFileObjects[i].sample.angle_x.min() + self.theta_offset th_max[i] = self.inFileObjects[i].sample.angle_x.max() + self.theta_offset th_len[i] = self.inFileObjects[i].sample.angle_x.shape[0] A4_vector = self.inFileObjects[i].detector.angle_x twoth_vector = self.getTwoTheta(corrected_pixel, array([A4_vector]).T) twoth_max[i] = twoth_vector.max() twoth_min[i] = twoth_vector.min() if th_len[i] > 1: th_step[i] = float(th_max[i] - th_min[i]) / th_len[i] else: th_step[i] = 0.0 #if twoth_len[i] > 1: #twoth_step[i] = float(twoth_max[i] - twoth_min[i]) / twoth_len[i] #else: #twoth_step[i] = 0.0 # take maximum A3 spacing as grid spacing for theta: th_stepsize = th_step.max() self.th_stepsize = th_stepsize # take the extrema as the limits of our new grid: th_min_min = th_min.min() self.th_min_min = th_min_min th_max_max = th_max.max() self.th_max_max = th_max_max th_steps = int(float(th_max_max - th_min_min) / th_stepsize) self.th_steps = th_steps # take 1/80 deg as grid spacing for 2theta: twoth_stepsize = 1.0/80.0 self.twoth_stepsize = twoth_stepsize # take the extrema as the limits of our new grid: twoth_min_min = twoth_min.min() self.twoth_min_min = twoth_min_min twoth_max_max = twoth_max.max() self.twoth_max_max = twoth_max_max twoth_steps = int(round(float( twoth_max_max - twoth_min_min ) / twoth_stepsize)) self.twoth_steps = twoth_steps th_twoth_data_extent = (twoth_min_min,twoth_max_max,th_min_min,th_max_max) #th_twoth_data = zeros((th_steps, twoth_steps, 4)) print th_min_min, th_max_max, th_steps print twoth_min_min, twoth_max_max, twoth_steps twoth_bin_edges = (arange(twoth_steps + 1)*twoth_stepsize) + twoth_min_min #self.twoth_bin_edges = twoth_bin_edges th_bin_edges = (arange(th_steps + 1)*th_stepsize) + th_min_min #self.th_bin_edges = th_bin_edges th_2th_array = zeros((th_steps, twoth_steps, 4)) for i in range(num_files): inData = self.inFileObjects[i] #pixel_vector = arange(609.0,0.0,-1.0) pixel_vector = arange(609.) intens_correction, pixel_correction = self.correctionFromPixel(pixel_vector) corrected_pixel = pixel_vector + pixel_correction intens = inData.detector.counts #cut off the last bit of intens_correction (which is larger by one than intens, because #we're making edges intens_correction = intens_correction[:-1] corrected_I = intens / (1.0 + intens_correction) #corrected_I = intens th = inData.sample.angle_x + self.theta_offset # need one more bin edge than data points: th_vector = zeros(len(th) + 1) th_vector[:len(th)] = th # this fails if there's only 1 theta value for the data file th_vector[-1] = th_vector[-2] + (th_vector[-2] - th_vector[-3]) print th_vector th_vector_comp = (arange(th_len[i] + 1.0)*th_step[i]) + th_min[i] print th_vector_comp #self.th_vector = th_vector #th_array = array([th_vector]).T + zeros(shape(intens)) # if the normalization is chosen to be vs. time instead of vs. monitor counts, the change is # made here: if self.normalization == 'time': monitor_vector = inData.monitor.count_time else: # self.normalization = monitor by default monitor_vector = inData.monitor.counts monitor_array = array([monitor_vector]).T + zeros(shape(intens)) pixel_array = ones(shape(intens)) A4_vector = inData.detector.angle_x if ( (A4_vector.max() - A4_vector.min() ) < instr_resolution ): #then the detector is fixed and we can pass a single 2theta vector to rebin2d twoth_vector = self.getTwoTheta(corrected_pixel,A4_vector.min()) #self.twoth_vector = twoth_vector new_data = reb.rebin2d(th_vector,twoth_vector,corrected_I.astype('float64'),th_bin_edges,twoth_bin_edges) #print th_vector.shape, twoth_vector.shape, corrected_I.shape, th_bin_edges.shape, twoth_bin_edges.shape #new_data = reb.rebin2d(twoth_vector,th_vector,intens,twoth_bin_edges,th_bin_edges) #print new_data new_pixelcount = reb.rebin2d(th_vector,twoth_vector,pixel_array.astype('float64'),th_bin_edges,twoth_bin_edges) new_mon = reb.rebin2d(th_vector,twoth_vector,monitor_array.astype('float64'),th_bin_edges,twoth_bin_edges) #new_pixelcount = reb.rebin2d(twoth_vector,th_vector,pixel_array,twoth_bin_edges,th_bin_edges) #new_mon = reb.rebin2d(twoth_vector,th_vector,monitor_array,twoth_bin_edges,th_bin_edges) th_2th_array[:,:,0] += new_data th_2th_array[:,:,1] += new_pixelcount th_2th_array[:,:,2] += new_mon else: #then the detector is not fixed, and we have to pass in each A4 value at a time to rebin for j in range(th_vector.shape[0]-1): twoth_vector = self.getTwoTheta(corrected_pixel,A4_vector[j]) #print th_vector.shape, twoth_vector.shape, corrected_I.shape, th_bin_edges.shape, twoth_bin_edges.shape new_data = reb.rebin(twoth_vector,corrected_I[j].astype('float64'),twoth_bin_edges) #new_data = reb.rebin2d(twoth_vector,th_vector[j],corrected_I[:,j],twoth_bin_edges,th_bin_edges) new_pixelcount = reb.rebin(twoth_vector,pixel_array[j].astype('float64'),twoth_bin_edges) new_mon = reb.rebin(twoth_vector,monitor_array[j].astype('float64'),twoth_bin_edges) print j th_2th_array[j,:,0] += new_data th_2th_array[j,:,1] += new_pixelcount th_2th_array[j,:,2] += new_mon print('loaded: ' + inData.name) nonzero_pixels = (th_2th_array[:,:,1] > 0) monitor_total = th_2th_array[:,:,2][nonzero_pixels] avg = th_2th_array[:,:,0][nonzero_pixels] / double(monitor_total) th_2th_array[:,:,3][nonzero_pixels] = avg self.th_2th_array = th_2th_array th2th_params = { 'description': self.inFileObjects[0].description, 'x_max': twoth_min_min, 'x_min': twoth_max_max, 'x_steps': twoth_steps, 'y_max': th_max_max, 'y_min': th_min_min, 'y_steps': th_steps, 'x_units': '$2\\theta ({}^{\circ})$', 'y_units': '$\\theta ({}^{\circ})$' } twoth_th_array = flipud(th_2th_array.swapaxes(0,1)) # cut off stuff that should really be zero - bad fp stuff twoth_th_array[:,:,3][twoth_th_array[:,:,3] < 1e-16] = 0. title = 'dataset ' + str(self.number) + ': th2th_data' self.th2th_data = plottable_2d_data(twoth_th_array, th2th_params, self, title = title) return