def convert_to_2theta(engine, two_theta, instrument_setup, roi_vec, geometry_shift, ws_name): # load instrument: as it changes pyrs_reducer = reduce_hb2b_pyrs.PyHB2BReduction(instrument_setup, 1.239) pyrs_reducer.build_instrument(two_theta, geometry_shift.center_shift_z, geometry_shift.center_shift_x, geometry_shift.center_shift_y, geometry_shift.rotation_x, geometry_shift.rotation_y, geometry_shift.rotation_z) # reduce data min_2theta = 8. max_2theta = 64. num_bins = 1800 # reduce PyRS (pure python) curr_id = engine.current_data_id vec_2theta, vec_hist = pyrs_reducer.reduce_to_2theta_histogram(counts_array=engine.get_counts(curr_id), mask=roi_vec, x_range=(min_2theta, max_2theta), num_bins=num_bins, is_point_data=True, use_mantid_histogram=False) CreateWorkspace(DataX=vec_2theta, DataY=vec_hist, DataE=np.sqrt(vec_hist), NSpec=1, OutputWorkspace=ws_name) return vec_2theta, vec_hist
def create_instrument(test_data_file, calibrated, pixel_number): """ Create instruments: PyRS and Mantid :param calibrated: :param pixel_number: :return: """ # instrument instrument = calibration_file_io.import_instrument_setup( xray_2k_instrument_file) # 2theta two_theta = 35. arm_length_shift = 0. center_shift_x = 0. center_shift_y = 0. rot_x_flip = 0. rot_y_flip = 0. rot_z_spin = 0. if False: center_shift_x = 1.0 * (random.random() - 0.5) * 2.0 center_shift_y = 1.0 * (random.random() - 0.5) * 2.0 arm_length_shift = (random.random() - 0.5) * 2.0 # 0.416 + (random.random() - 0.5) * 2.0 # calibration rot_x_flip = 2.0 * (random.random() - 0.5) * 2.0 rot_y_flip = 2.0 * (random.random() - 0.5) * 2.0 rot_z_spin = 2.0 * (random.random() - 0.5) * 2.0 # END-IF: arbitrary calibration test_calibration = AnglerCameraDetectorShift() test_calibration.center_shift_x = center_shift_x test_calibration.center_shift_y = center_shift_y test_calibration.center_shift_z = arm_length_shift test_calibration.rotation_x = rot_x_flip test_calibration.rotation_y = rot_y_flip test_calibration.rotation_z = rot_z_spin # reduction engine engine = reduction_manager.HB2BReductionManager() test_data_id, two_the_tmp = engine.load_data(data_file_name=test_data_file, target_dimension=pixel_number, load_to_workspace=True) # load instrument pyrs_reducer = reduce_hb2b_pyrs.PyHB2BReduction(instrument) pyrs_reducer.build_instrument(two_theta, arm_length_shift, center_shift_x, center_shift_y, rot_x_flip, rot_y_flip, rot_z_spin) mantid_reducer = None # mantid_reducer = reduce_hb2b_mtd.MantidHB2BReduction() # data_ws_name = engine.get_raw_data(test_data_id, is_workspace=True) # mantid_reducer.set_workspace(data_ws_name) # mantid_reducer.load_instrument(two_theta, xray_idf_name, test_calibration) return engine, pyrs_reducer, mantid_reducer
def setup_reduction_engine(self, workspace, sub_run, geometry_calibration): """Setup reduction engine to reduce data (workspace or vector) to 2-theta ~ I Builds a new 2theta pixel map if none is present or if the detector has moved Parameters ---------- workspace : HidraWorkspace workspace with detector counts and position sub_run : integer sub run number in workspace to reduce geometry_calibration : instrument_geometry.DENEXDetectorShift instrument geometry to calculate diffraction pattern Returns ------- None """ # Get the raw data raw_count_vec = workspace.get_detector_counts(sub_run) # Retrieve 2-theta and L2 from loaded workspace (DAS) two_theta = workspace.get_detector_2theta(sub_run) l2 = workspace.get_l2(sub_run) if sub_run > 1: rebuild_instrument = two_theta != workspace.get_detector_2theta( sub_run - 1) else: rebuild_instrument = True if self._last_reduction_engine is None: rebuild_instrument = True # Convert 2-theta from DAS convention to Mantid/PyRS convention mantid_two_theta = -two_theta # Set up reduction engine if not rebuild_instrument: reduction_engine = self._last_reduction_engine reduction_engine.set_raw_counts(raw_count_vec) else: reduction_engine = reduce_hb2b_pyrs.PyHB2BReduction( workspace.get_instrument_setup()) # Set up reduction engine reduction_engine.set_experimental_data(mantid_two_theta, l2, raw_count_vec) reduction_engine.build_instrument(geometry_calibration) return reduction_engine
def create_instrument_load_data(instrument, calibrated, pixel_number): """ Create instruments: PyRS and Mantid and load data :param instrument: name of instrument :param calibrated: :param pixel_number: :return: """ # instrument if instrument == 'XRay-XRayMock': hydra_idf = xray_2k_instrument_file mantid_idf = xray_idf_name two_theta = xray_2theta test_data_file = test_xray_data elif instrument == 'HBZ': hydra_idf = hbz_instrument_file mantid_idf = hbz_idf two_theta = hbz_2theta test_data_file = test_hbz_data print('Loaded {} and {} to compare @ 2theta = {} degree' ''.format(hydra_idf, mantid_idf, two_theta)) else: raise RuntimeError('Instrument {} does not have test data and IDF'.format(instrument)) print('----------- IDF in Test: {} vs {} ---------------'.format(hydra_idf, mantid_idf)) instrument = calibration_file_io.import_instrument_setup(hydra_idf) # instrument geometry calibration if calibrated: # Note: README/TODO-ING: ONLY shift Y center_shift_x = int(1000. * (random.random() - 0.5) * 2.0) / 1000. center_shift_y = int(1000. * (random.random() - 0.5) * 2.0) / 1000. arm_length_shift = int(1000. * (random.random() - 0.5) * 2.0) / 1000. # 0.416 + (random.random() - 0.5) * 2.0 # calibration FIXME - Disable rotation calibration to find out the source of difference: 10-17 vs 10-7 rot_x_flip = int(1000. * 2.0 * (random.random() - 0.5) * 5.0) / 1000. rot_y_flip = int(1000. * 2.0 * (random.random() - 0.5) * 5.0) / 1000. rot_z_spin = int(1000. * 2.0 * (random.random() - 0.5) * 5.0) / 1000. print('[(Random) Calibration Setup]\n Shift Linear (X, Y, Z) = {}, {}, {}\n Shift Rotation ' '(X, Y, Z) = {}, {}, {}' ''.format(center_shift_x, center_shift_y, arm_length_shift, rot_x_flip, rot_y_flip, rot_z_spin)) else: arm_length_shift = center_shift_x = center_shift_y = 0. rot_x_flip = rot_y_flip = rot_z_spin = 0. # END-IF: arbitrary calibration test_calibration = AnglerCameraDetectorShift() test_calibration.center_shift_x = center_shift_x test_calibration.center_shift_y = center_shift_y test_calibration.center_shift_z = arm_length_shift test_calibration.rotation_x = rot_x_flip test_calibration.rotation_y = rot_y_flip test_calibration.rotation_z = rot_z_spin # reduction engine engine = reduction_manager.HB2BReductionManager() test_data_id, two_theta_tmp = engine.load_data(data_file_name=test_data_file, target_dimension=pixel_number, load_to_workspace=True) # load instrument pyrs_reducer = reduce_hb2b_pyrs.PyHB2BReduction(instrument) pyrs_reducer.build_instrument(two_theta, arm_length_shift, center_shift_x, center_shift_y, rot_x_flip, rot_y_flip, rot_z_spin) mantid_reducer = reduce_hb2b_mtd.MantidHB2BReduction() data_ws_name = engine.get_raw_data(test_data_id, is_workspace=True) mantid_reducer.set_workspace(data_ws_name) mantid_reducer.build_instrument(two_theta, mantid_idf, test_calibration) return engine, pyrs_reducer, mantid_reducer
def main(argv): """ main args :param argv: :return: """ # init setup image_file = 'tests/testdata/LaB6_10kev_35deg-00004_Rotated.tif' two_theta = 0. # it is 35 degree... using 0 for debugging # load masks temp_list = [ 'Chi_0_Mask.xml', 'Chi_10_Mask.xml', 'Chi_20_Mask.xml', 'Chi_30_Mask.xml', 'NegZ_Mask.xml' ] mask_xml_list = [ os.path.join('tests/testdata/masks', xml_name) for xml_name in temp_list ] # Now it is the setup for real reduction pixel_length = 1024 # Load raw data hb2b_ws_name, hb2b_count_vec = load_data_from_tif(image_file, pixel_length) # Masking masking_list = list() # tuple: mask array and mask workspace if pixel_length == 2048: for mask_xml in mask_xml_list: if 'Chi_0' in mask_xml: is_mask = True print('mask {} with is_mask = True'.format(mask_xml)) else: is_mask = False mask_array, mask_ws_name = create_mask(mask_xml, pixel_length**2, is_mask) masking_list.append((mask_array, mask_ws_name)) # create instrument if pixel_length == 2048: num_rows = 2048 num_columns = 2048 pixel_size_x = 0.00020 pixel_size_y = 0.00020 idf_name = 'Xray_HB2B_2K.xml' elif pixel_length == 1024: num_rows = 2048 / 2 num_columns = 2048 / 2 pixel_size_x = 0.00020 * 2 pixel_size_y = 0.00020 * 2 idf_name = 'Xray_HB2B_1K.xml' idf_name = 'XRay_Definition_1K.xml' else: raise RuntimeError('Wrong setup') hb2b_builder = reduce_hb2b_pyrs.PyHB2BReduction(num_rows, num_columns, pixel_size_x, pixel_size_y) idf_name = os.path.join('tests/testdata/', idf_name) # load instrument arm_length = 0.416 # calibration rot_x_flip = 0. # 0.01 rot_y_flip = 30. # with trouble -0.142 rot_z_spin = 0. # 0.98 # still no good center_shift_x = 0. # 0.001 center_shift_y = 0. # -0.02 hb2b_pixel_matrix = load_instrument(hb2b_builder, arm_length, two_theta, center_shift_x, center_shift_y, rot_x_flip, rot_y_flip, rot_z_spin, hb2b_ws_name, idf_name, pixel_length) for mask_index in [0]: mask_array, mask_ws_name = masking_list[mask_index] reduce_to_2theta(hb2b_builder, hb2b_pixel_matrix, hb2b_ws_name, hb2b_count_vec, mask_array, mask_ws_name, num_bins=2500)
def peaks_alignment_score(x, engine, hb2b_setup, two_theta, roi_vec_set, plot=False, ScalarReturn=False): """ Cost function for peaks alignment :param x: :param engine: :param hb2b_setup: :param two_theta: :param roi_vec_set: list/array of ROI/mask vector :param plot: :return: """ peak_centers = '17.5,24.5,30.25,35.2,39.4,43.2,50.0,53.5,56.4,59.45' fit_windows = '16,19,23,26,29,32,33,37,38,41,42,44.5,49.1,51.5,51.5,55,55,58,58,61' peak_centers = '24.5,30.25,50.0,53.5,56.4,59.45' fit_windows = '23,26,29,32,49.1,51.5,51.5,55,55,58,58,61' # check assert isinstance(roi_vec_set, list), 'must be list' if len(roi_vec_set) < 2: raise RuntimeError('User must specify more than 1 ROI/MASK vector') else: num_reduced_set = len(roi_vec_set) # convert the input X array (to be refined) to geometry calibration values # geom_calibration = instrument_geometry.AnglerCameraDetectorShift() # geom_calibration.center_shift_x = x[0] # geom_calibration.center_shift_y = x[1] # geom_calibration.center_shift_z = x[2] # geom_calibration.rotation_x = x[3] # geom_calibration.rotation_y = x[4] # geom_calibration.rotation_z = x[5] #geom_shift = instrument_geometry.AnglerCameraDetectorShift( x[0], x[1], x[2], x[3], x[4], x[5] ) #AnglerCameraDetectorGeometry.apply_shift( instrument_geometry.AnglerCameraDetectorShift( x[0], x[1], x[2], x[3], x[4], x[5] ) ) # load instrument: as it changes pyrs_reducer = reduce_hb2b_pyrs.PyHB2BReduction(hb2b_setup, 1.239) pyrs_reducer.build_instrument_prototype(two_theta, x[0], x[1], x[2], x[3], x[4], x[5]) # pyrs_reducer.build_instrument_prototype() Eta_val = pyrs_reducer.get_eta_value() # reduce data reduced_data_set = [None] * num_reduced_set for i_roi in range(num_reduced_set): ws_name_i = 'reduced_data_{:02}'.format(i_roi) out_peak_pos_ws = 'peaks_positions_{:02}'.format(i_roi) fitted_ws = 'fitted_peaks_{:02}'.format(i_roi) # Define Mask Mask = np.zeros_like(Eta_val) if abs(roi_vec_set[i_roi]) == roi_vec_set[i_roi]: index = np.where((Eta_val < (roi_vec_set[i_roi]+5)) == (Eta_val > (roi_vec_set[i_roi]-5)))[0] else: index = np.where((Eta_val > (roi_vec_set[i_roi]-5)) == (Eta_val < (roi_vec_set[i_roi]+5)))[0] Mask[index] = 1. # reduce reduced_i = convert_to_2theta(engine, pyrs_reducer, Mask, ws_name_i) # fit peaks FitPeaks(InputWorkspace=ws_name_i, OutputWorkspace=out_peak_pos_ws, StartWorkspaceIndex=0, StopWorkspaceIndex=0, PeakCenters=peak_centers, FitWindowBoundaryList=fit_windows, FittedPeaksWorkspace=fitted_ws, OutputPeakParametersWorkspace='hb2b_rotate_p30deg_reduced_FITS', # FIXME - need to give a good name too OutputParameterFitErrorsWorkspace='hb2b_rotate_p30deg_reduced_Errors') reduced_data_set[i_roi] = reduced_i, ws_name_i, out_peak_pos_ws, fitted_ws # END-FOR # calculate the quality of peak alignment for each pair of ROI residual = None for roi_i, roi_j in list(itertools.combinations(range(num_reduced_set), 2)): # get data r_t_i = reduced_data_set[roi_i] r_t_j = reduced_data_set[roi_j] # calculate residual/cost num_peaks = len(mtd[r_t_i[2]].readY(0)) residual_sq = np.zeros(shape=(num_peaks,), dtype='float') for p_index in range(num_peaks): pos_pos_i = mtd[r_t_i[2]].readY(0)[p_index] neg_pos_i = mtd[r_t_j[2]].readY(0)[p_index] if pos_pos_i < 0. and neg_pos_i < 0.: # both failed to fit residual_sq[p_index] = 200 ** 2 elif pos_pos_i * neg_pos_i < 0.: # 1 failed to fit residual_sq[p_index] = 100 ** 2 else: residual_sq[p_index] = ((pos_pos_i - neg_pos_i) ** 2) # END-FOR if residual is None: residual = residual_sq else: residual = np.concatenate([residual, residual_sq]) # END-IF-ELSE c_n_2 = math.factorial(num_reduced_set) / (math.factorial(2) * math.factorial(num_reduced_set - 2)) norm_cost = residual.sum() / c_n_2 # plot num_rows = 1 + num_reduced_set / 2 + num_reduced_set % 2 ax1 = plt.subplot(num_rows, 1, num_rows) ax1.margins(0.05) # Default margin is 0.05, value 0 means fit colors = ['black', 'red', 'blue', 'green', 'yellow'] for roi_i in range(num_reduced_set): r_t_i = reduced_data_set[roi_i] ax1.plot(r_t_i[0][0], r_t_i[0][1], color=colors[roi_i % 5]) ax1.set_title('Normalized Cost = {}'.format(norm_cost)) for roi_i in range(num_reduced_set): index_i = roi_i + 1 print('subplot: {}, {}, {}'.format(num_rows, 2, index_i)) ax2 = plt.subplot(num_rows, 2, index_i) ax2.plot(reduced_data_set[roi_i][0][0], reduced_data_set[roi_i][0][1], color='black') ax2.plot(mtd[reduced_data_set[roi_i][3]].readX(0), mtd[reduced_data_set[roi_i][3]].readY(0), color='red') ax2.set_title('{}'.format(roi_i)) if plot: plt.show() else: plt.savefig('Round{:010}.png'.format(GlobalParameter.global_curr_sequence)) GlobalParameter.global_curr_sequence += 1 plt.clf() # print ('Parameters: {}'.format(x)) # print ('Fitted Peaks +: {}'.format(mtd[P30_Fit].readY(0))) # print ('Fitted Peaks -: {}'.format(mtd[N30_Fit].readY(0))) print('Residual = {}'.format(norm_cost)) if ScalarReturn: return np.sum(residual) else: return residual
def main(): import os # Set up # data file if False: # pyrs_root = '/SNS/users/hcf/HFIR_TESTING/' # test_file_name = 'LaB6_10kev_35deg-00004.xml' # Vanadium = 'Vanadium.xml' test_file_name = 'tests/testdata/BNT_7BT_2KNN_6kV_mm-03425-001.xml' pos_mask_h5 = None neg_mask_h5 = None else: test_file_name = 'tests/testdata/LaB6_10kev_35deg-00004_Rotated_TIF.h5' pos_mask_h5 = 'tests/testdata/masks/Chi_30.hdf5' neg_mask_h5 = 'tests/testdata/masks/Chi_Neg30.hdf5' # instrument geometry if False: idf_name = os.path.join(pyrs_root, 'XRay_Definition_1K.xml') else: idf_name = 'tests/testdata/xray_data/XRay_Definition_2K.txt' # Load, mask and reduce data if False: # old way os.system('cp ' + idf_name + ' ~/.mantid/instrument/HB2B_Definition.xml') # Load data LoadSpice2D(Filename=hb2b_file_name, OutputWorkspace='hb2b') LoadSpice2D(Filename=hb2b_Vfile_name, OutputWorkspace='hb2b_V') ws_name = test_rotate_2theta(idf_name, 'hb2b', 'hb2b_rotate') vanadium = test_rotate_2theta(idf_name, 'hb2b_V', 'hb2b_V_rotate') vanadium_line = convert_to_2thetaVanadium(vanadium, num_bins=1900, Mask=None) convert_to_2theta(ws_name, vanadium_line) NegMask = 'NegMask' PosMask = 'PosMask' ZeMask = 'ZeroMask' p10Mask = 'p10Mask' p20Mask = 'p20Mask' p30Mask = 'p30Mask' n30Mask = 'n30Mask' LoadMask(Instrument='HB2B', InputFile='/SNS/users/hcf/HFIR_TESTING/NegZ_Mask.xml', OutputWorkspace=NegMask) LoadMask(Instrument='HB2B', InputFile='/SNS/users/hcf/HFIR_TESTING/Chi_30_Mask.xml', OutputWorkspace=p30Mask) InvertMask(InputWorkspace=NegMask, OutputWorkspace=PosMask) InvertMask(InputWorkspace=p30Mask, OutputWorkspace=p30Mask) CloneWorkspace(InputWorkspace=p30Mask, OutputWorkspace=n30Mask) MaskDetectors(Workspace=p30Mask, MaskedWorkspace=PosMask) MaskDetectors(Workspace=n30Mask, MaskedWorkspace=NegMask) WS_p30deg = test_rotate_2theta(idf_name, 'hb2b', 'hb2b_rotate_p30deg') WS_n30deg = test_rotate_2theta(idf_name, 'hb2b', 'hb2b_rotate_n30deg') MaskDetectors(WS_p30deg, MaskedWorkspace=p30Mask) MaskDetectors(WS_n30deg, MaskedWorkspace=n30Mask) vanadium_P30 = convert_to_2thetaVanadium(vanadium, num_bins=1900, Mask=p30Mask) vanadium_N30 = convert_to_2thetaVanadium(vanadium, num_bins=1900, Mask=n30Mask) elif False: # build instrument: for FUN instrument = calibration_file_io.import_instrument_setup(idf_name) # 2theta two_theta = -35. # TODO - TONIGHT 1 - Make this user specified value calibration = [ -2.28691912e-04, 3.42766839e-06, -1.99762398e-03, -5.59805308e-02, -8.32593462e-01, 7.66556036e-04 ] arm_length_shift = calibration[2] center_shift_x = calibration[0] center_shift_y = calibration[1] rot_x_flip = calibration[3] rot_y_flip = calibration[4] rot_z_spin = calibration[5] # reduction engine engine = reduction_manager.HB2BReductionManager() test_data_id = engine.load_data(data_file_name=test_file_name, target_dimension=2048, load_to_workspace=False) # load instrument pyrs_reducer = reduce_hb2b_pyrs.PyHB2BReduction(instrument, 1.239) pyrs_reducer.build_instrument(two_theta, arm_length_shift, center_shift_x, center_shift_y, rot_x_flip, rot_y_flip, rot_z_spin) # reduce data min_2theta = 8. max_2theta = 64. num_bins = 1800 # reduce PyRS (pure python) curr_id = engine.current_data_id # mask roi_vec_pos, mask_2theta, note = mask_util.load_pyrs_mask(pos_mask_h5) roi_vec_neg, mask_2thetA, notE = mask_util.load_pyrs_mask(neg_mask_h5) pos_2theta, pos_hist = pyrs_reducer.reduce_to_2theta_histogram( counts_array=engine.get_counts(curr_id), mask=roi_vec_pos, x_range=(min_2theta, max_2theta), num_bins=num_bins, is_point_data=True, use_mantid_histogram=False) neg_2theta, neg_hist = pyrs_reducer.reduce_to_2theta_histogram( counts_array=engine.get_counts(curr_id), mask=roi_vec_neg, x_range=(min_2theta, max_2theta), num_bins=num_bins, is_point_data=True, use_mantid_histogram=False) plt.plot(pos_2theta, pos_hist, color='red') plt.plot(neg_2theta, neg_hist, color='blue') plt.show() print('RESULT EXAMINATION IS OVER') else: import time t_start = time.time() # reduction engine engine = reduction_manager.HB2BReductionManager() test_data_id = engine.load_data(data_file_name=test_file_name, target_dimension=2048, load_to_workspace=False) # instrument instrument = calibration_file_io.import_instrument_setup(idf_name) # mask roi_vec_pos, mask_2theta, note = mask_util.load_pyrs_mask(pos_mask_h5) roi_vec_neg, mask_2thetA, notE = mask_util.load_pyrs_mask(neg_mask_h5) x0 = [0, 0, -0.002, -0.007, -0.922, 0] # x0 = [-1.] # engine, hb2b_setup, positive_roi_vec, negative_roi_vec DE_Res = leastsq(MinDifference, np.array(x0), args=(engine, instrument, roi_vec_pos, roi_vec_neg), xtol=1e-15, maxfev=3000, epsfcn=1e-2) t_stop = time.time() print('Total Time: {}'.format(t_stop - t_start)) print(DE_Res[0]) print(DE_Res[1]) DD = 0.0 D_Shift = 0 Center_X = -0.002 Center_Y = -0.007 Flip = -1 Spin = 0.0 # DE_Res = leastsq(MinDifference, [-1], xtol=1e-15, maxfev=3000) # END-IF-ELSE return
def peaks_alignment_score(x, engine, hb2b_setup, two_theta, roi_vec_set, plot=False, ScalarReturn=False): """ Cost function for peaks alignment :param x: :param engine: :param hb2b_setup: :param two_theta: :param roi_vec_set: list/array of ROI/mask vector :param plot: :return: """ peak_centers = '17.5,24.5,30.25,35.2,39.4,43.2,53.5' fit_windows = '16,19,23,26,29,32,33,37,38,41,42,44.5,51.5,55' peak_pos = [17.5, 24.5, 30.25, 35.2, 39.4, 43.2, 53.5] peak_pos = [25.5, 30.25, 35.2, 39.4, 43.2, 50.7, 54., 57., 59] # check #assert isinstance(roi_vec_set, list), 'must be list' if len(roi_vec_set) < 2: raise RuntimeError('User must specify more than 1 ROI/MASK vector') else: num_reduced_set = len(roi_vec_set) num_peaks = len(peak_pos) # convert the input X array (to be refined) to geometry calibration values geom_calibration = AnglerCameraDetectorShift() geom_calibration.center_shift_x = x[0] geom_calibration.center_shift_y = x[1] geom_calibration.center_shift_z = x[2] geom_calibration.rotation_x = x[3] geom_calibration.rotation_y = x[4] geom_calibration.rotation_z = x[5] # load instrument: as it changes pyrs_reducer = reduce_hb2b_pyrs.PyHB2BReduction(hb2b_setup, 1.239) pyrs_reducer.build_instrument(two_theta, geom_calibration.center_shift_z, geom_calibration.center_shift_x, geom_calibration.center_shift_y, geom_calibration.rotation_x, geom_calibration.rotation_y, geom_calibration.rotation_z) Eta_val = pyrs_reducer.get_eta_value() # reduce data reduced_data_set = [None] * num_reduced_set if plot: fig, ax = plt.subplots(1, 1, figsize=(10, 10)) for i_roi in range(num_reduced_set): # Define Mask Mask = np.zeros_like(Eta_val) if abs(roi_vec_set[i_roi]) == roi_vec_set[i_roi]: index = np.where((Eta_val < (roi_vec_set[i_roi] + 5)) == ( Eta_val > (roi_vec_set[i_roi] - 5)))[0] else: index = np.where((Eta_val > (roi_vec_set[i_roi] - 5)) == ( Eta_val < (roi_vec_set[i_roi] + 5)))[0] Mask[index] = 1. #x_vec, y_vec = convert_to_2theta(engine, pyrs_reducer, Mask, 18, 63, 1800 ) vec_x, vec_y = convert_to_2theta(engine, pyrs_reducer, Mask, 18, 63, 1800) ax.plot(vec_x.T, vec_y.T, label=roi_vec_set[i_roi]) ax.set_ylabel('Int (cts.)') ax.set_ylabel('2theta (deg.)') handles, labels = ax.get_legend_handles_labels() fig.legend(handles, labels, loc='upper center') plt.show() return for i_roi in range(num_reduced_set): Peaks = [None] * num_peaks # Define Mask Mask = np.zeros_like(Eta_val) if abs(roi_vec_set[i_roi]) == roi_vec_set[i_roi]: index = np.where((Eta_val < (roi_vec_set[i_roi] + 5)) == ( Eta_val > (roi_vec_set[i_roi] - 5)))[0] else: index = np.where((Eta_val > (roi_vec_set[i_roi] - 5)) == ( Eta_val < (roi_vec_set[i_roi] + 5)))[0] Mask[index] = 1. for i_peak in range(num_peaks): # reduce Peaks[i_peak] = convert_to_2theta(engine, pyrs_reducer, Mask, peak_pos[i_peak] - 1, peak_pos[i_peak] + 1, 60)[1] reduced_data_set[i_roi] = Peaks # END-FOR # calculate the quality of peak alignment for each pair of ROI residual = None for i_roi in range(num_reduced_set): for peak_i, peak_j in list(itertools.combinations(range(num_peaks), 2)): # get data #residual_sq = 1. / np.min( np.corrcoef( reduced_data_set[i_roi][peak_i], reduced_data_set[i_roi][peak_j] ) ) temp_p1 = reduced_data_set[i_roi][peak_i] temp_p2 = reduced_data_set[i_roi][peak_j] residual_sq = ( 1. / np.correlate(temp_p1 / np.linalg.norm(temp_p1), temp_p2 / np.linalg.norm(temp_p2))) - 1. # residual_sq = np.correlate( reduced_data_set[i_roi][peak_i], reduced_data_set[i_roi][peak_j] ) if not np.isfinite(residual_sq): residual_sq = np.array([1000.]) if residual is None: residual = residual_sq else: residual = np.concatenate([residual, residual_sq]) # END-IF-ELSE c_n_2 = math.factorial(num_reduced_set) / ( math.factorial(2) * math.factorial(num_reduced_set - 2)) norm_cost = residual.sum() / c_n_2 print('Residual = {}'.format(norm_cost)) if ScalarReturn: return np.sum(residual) else: return residual
def get_alignment_residual(x, engine, hb2b_setup, two_theta, roi_vec_set): """ Cost function for peaks alignment to determine wavelength :param x: list/array of detector shift/rotation and neutron wavelength values :x[0]: shift_x, x[1]: shift_y, x[2]: shift_z, x[3]: rot_x, x[4]: rot_y, x[5]: rot_z, x[6]: wavelength :param engine: :param hb2b_setup: HB2B class containing instrument definitions :param two_theta: list/array of detector positions :param roi_vec_set: list/array of ROI/mask vector :return: """ GlobalParameter.global_curr_sequence += 1 residual = np.array([]) resNone = 0. TTH_Calib = np.arcsin(x[6] / 2. / dSpace) * 360. / np.pi TTH_Calib = TTH_Calib[~np.isnan(TTH_Calib)] background = LinearModel() for i_tth in range(len(two_theta)): #reduced_data_set[i_tth] = [None] * num_reduced_set # load instrument: as it changes pyrs_reducer = reduce_hb2b_pyrs.PyHB2BReduction(hb2b_setup, x[6]) pyrs_reducer.build_instrument_prototype(two_theta[i_tth], x[0], x[1], x[2], x[3], x[4], x[5]) DetectorAngle = np.abs(two_theta[i_tth]) mintth = DetectorAngle - 8.0 maxtth = DetectorAngle + 8.8 Eta_val = pyrs_reducer.get_eta_value() maxEta = np.max(Eta_val) - 2 minEta = np.min(Eta_val) + 2 peak_centers = '' fit_windows = '' FitModel = lmfit.Model(BackGround) pars1 = FitModel.make_params(p0=100, p1=1, p2=0.01) Peaks = [] CalibPeaks = TTH_Calib[np.where( (TTH_Calib > mintth) == (TTH_Calib < maxtth))[0]] for ipeak in range(len(CalibPeaks)): if (CalibPeaks[ipeak] > mintth) and (CalibPeaks[ipeak] < maxtth): peak_centers += '%.4f,' % CalibPeaks[ipeak] fit_windows += '%.4f,%.4f,' % (CalibPeaks[ipeak] - 1, CalibPeaks[ipeak] + 1) Peaks.append(ipeak) PeakModel = GaussianModel(prefix='g%d_' % ipeak) FitModel += PeakModel pars1.update(PeakModel.make_params()) pars1['g%d_center' % ipeak].set(value=CalibPeaks[ipeak], min=CalibPeaks[ipeak] - 2, max=CalibPeaks[ipeak] + 2) pars1['g%d_sigma' % ipeak].set(value=0.5, min=1e-3, max=1.0) pars1['g%d_amplitude' % ipeak].set(value=50., min=0, max=1e6) # peak_centers = peak_centers[:-1] # fit_windows = fit_windows[:-1] if peak_centers == '': residual = np.concatenate([residual, np.array([20000])]) else: # reduce data # for i_roi in range( len( roi_vec_set ) ): print(minEta, maxEta) eta_roi_vec = np.arange(minEta, maxEta + 0.2, 2) num_rows = 1 + len(Peaks) / 2 + len(Peaks) % 2 ax1 = plt.subplot(num_rows, 1, num_rows) ax1.margins(0.05) # Default margin is 0.05, value 0 means fit for i_roi in range(len(roi_vec_set)): ws_name_i = 'reduced_data_{:02}'.format(i_roi) out_peak_pos_ws = 'peaks_positions_{:02}'.format(i_roi) fitted_ws = 'fitted_peaks_{:02}'.format(i_roi) # Define Mask Mask = np.zeros_like(Eta_val) if abs(eta_roi_vec[i_roi]) == eta_roi_vec[i_roi]: index = np.where((Eta_val < (eta_roi_vec[i_roi] + 1)) == ( Eta_val > (eta_roi_vec[i_roi] - 1)))[0] else: index = np.where((Eta_val > (eta_roi_vec[i_roi] - 1)) == ( Eta_val < (eta_roi_vec[i_roi] + 1)))[0] Mask[index] = 1. # reduce reduced_i = convert_to_2theta(engine, pyrs_reducer, Mask, ws_name_i, 'SimulatedData_%d' % np.abs(DetectorAngle), min_2theta=mintth, max_2theta=maxtth, num_bins=400) Fitresult = FitModel.fit(reduced_i[1], pars1, x=reduced_i[0]) # print ('\n\n\n' ) for p_index in Peaks: residual_sq = ( 100.0 * (Fitresult.params['g%d_center' % p_index].value - CalibPeaks[p_index]))**2 resNone += Fitresult.params[ 'g%d_center' % p_index].value - CalibPeaks[p_index] # print( Fitresult.params['g%d_center'%p_index].value, CalibPeaks[p_index], Fitresult.params['g%d_center'%p_index] - CalibPeaks[p_index] ) residual = np.concatenate( [residual, np.array([residual_sq])]) # print ('\n\n\n' ) # plot backgroundShift = np.average( BackGround(reduced_i[0], Fitresult.params['p0'].value, Fitresult.params['p1'].value, Fitresult.params['p2'].value)) ax1.plot(reduced_i[0], reduced_i[1], color=colors[i_roi % 5]) for index_i in range(1, len(Peaks) + 1): ax2 = plt.subplot(num_rows, 2, index_i) ax2.plot(reduced_i[0], reduced_i[1], 'x', color='black') ax2.plot(reduced_i[0], Fitresult.best_fit, color='red') ax2.plot([CalibPeaks[p_index], CalibPeaks[p_index]], [ backgroundShift, backgroundShift + Fitresult.params['g0_amplitude'].value ], 'k', linewidth=2) ax2.set_xlim( [CalibPeaks[p_index] - 1.5, CalibPeaks[p_index] + 1.5]) plt.savefig('./FitFigures/Round{:010}_{:02}.png'.format( GlobalParameter.global_curr_sequence, i_tth)) plt.clf() # fit peaks # FitPeaks(InputWorkspace=ws_name_i, OutputWorkspace=out_peak_pos_ws, # StartWorkspaceIndex=0, StopWorkspaceIndex=0, # PeakCenters=peak_centers, # FitWindowBoundaryList=fit_windows, # FittedPeaksWorkspace=fitted_ws, # OutputPeakParametersWorkspace='hb2b_rotate_p30deg_reduced_FITS', # FIXME - need to give a good name too # OutputParameterFitErrorsWorkspace='hb2b_rotate_p30deg_reduced_Errors') # print ( "\n\n\n\n\n\n" ) # print ( mtd[ out_peak_pos_ws ].readY(0) ) # print ( CalibPeaks ) # print ( CalibPeaks - mtd[ out_peak_pos_ws ].readY(0) ) # print ( "\n\n\n\n\n\n" ) # plot # ax1.plot(reduced_i[0], reduced_i[1], color=colors[i_roi % 5]) # index_i = i_roi + 1 # ax2 = plt.subplot(num_rows, 2, index_i) # ax2.plot(reduced_i[0], reduced_i[1], color='black') # ax2.plot(mtd[fitted_ws].readX(0), mtd[fitted_ws].readY(0), color='red') # # # plt.savefig('Round{:010}_{:02}.png'.format(GlobalParameter.global_curr_sequence, i_tth)) # plt.clf() norm_cost = residual.sum() / (len(roi_vec_set) * len(two_theta)) print("\n\n\n") print('Residual = {}'.format(norm_cost)) print('Residual = {}'.format(resNone)) print("\n\n\n") return (residual)
def main(argv): """ main args :param argv: :return: """ import random # Init setup for instrument geometry pixel_length = 1024 pixel_length = 2048 # Data if pixel_length == 2048: image_file = 'tests/testdata/LaB6_10kev_35deg-00004_Rotated.tif' hb2b_ws_name, hb2b_count_vec = load_data_from_tif( image_file, pixel_length) else: bin_file = 'tests/testdata/LaB6_10kev_0deg-00000_Rotated.bin' hb2b_ws_name, hb2b_count_vec = load_data_from_bin(bin_file) # create instrument if pixel_length == 2048: num_rows = 2048 num_columns = 2048 pixel_size_x = 0.00020 pixel_size_y = 0.00020 idf_name = 'XRay_Definition_2K.xml' elif pixel_length == 1024: num_rows = 2048 / 2 num_columns = 2048 / 2 pixel_size_x = 0.00020 * 2 pixel_size_y = 0.00020 * 2 idf_name = 'XRay_Definition_1K.xml' else: raise RuntimeError('Wrong setup') from pyqr.utilities import calibration_file_io xray_instrument = calibration_file_io.InstrumentSetup() xray_instrument.detector_rows = num_rows xray_instrument.detector_columns = num_columns xray_instrument.pixel_size_x = pixel_size_x xray_instrument.pixel_size_y = pixel_size_y xray_instrument.arm_length = 0.416 # num_rows, num_columns, pixel_size_x, pixel_size_y hb2b_builder = reduce_hb2b_pyrs.PyHB2BReduction(xray_instrument) idf_name = os.path.join('tests/testdata/', idf_name) # load instrument for iter in range(1): if False: arm_length_shift = ( random.random() - 0.5) * 2.0 # 0.416 + (random.random() - 0.5) * 2.0 two_theta = 35. + (random.random() - 0.5) * 20. # calibration rot_x_flip = 2.0 * (random.random() - 0.5) * 2.0 rot_y_flip = 2.0 * (random.random() - 0.5) * 2.0 rot_z_spin = 2.0 * (random.random() - 0.5) * 2.0 center_shift_x = 1.0 * (random.random() - 0.5) * 2.0 center_shift_y = 1.0 * (random.random() - 0.5) * 2.0 else: arm_length_shift = 0. # arm length shift two_theta = 35. # calibration rot_x_flip = 0. # 2.0 * (random.random() - 0.5) * 2.0 rot_y_flip = 0. # 2.0 * (random.random() - 0.5) * 2.0 rot_z_spin = 0. # 2.0 * (random.random() - 0.5) * 2.0 center_shift_x = 0. # 1.0 * (random.random() - 0.5) * 2.0 center_shift_y = 0. # 1.0 * (random.random() - 0.5) * 2.0 # END hb2b_pixel_matrix = load_instrument(hb2b_builder, arm_length_shift, two_theta, center_shift_x, center_shift_y, rot_x_flip, rot_y_flip, rot_z_spin, hb2b_ws_name, idf_name, pixel_length)