예제 #1
0
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
예제 #2
0
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
예제 #3
0
    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
예제 #4
0
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
예제 #5
0
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)
예제 #6
0
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
예제 #7
0
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
예제 #9
0
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)
예제 #10
0
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)