From da41b4f02e14029ee2d226546cfdc90a0318fc28 Mon Sep 17 00:00:00 2001 From: Wenduo Zhou Date: Tue, 4 Dec 2018 21:30:47 -0500 Subject: [PATCH] Refs #32 and #36. Fixed MTEX header issue and progress in reduction. --- pyrs/core/polefigurecalculator.py | 62 ++++++++------------ pyrs/core/reductionengine.py | 78 ++++++++++++++++++++++++- pyrs/interface/gui_helper.py | 17 ++++++ pyrs/interface/textureanalysiswindow.py | 15 +---- 4 files changed, 122 insertions(+), 50 deletions(-) diff --git a/pyrs/core/polefigurecalculator.py b/pyrs/core/polefigurecalculator.py index f981bde64..a97d7e0dc 100644 --- a/pyrs/core/polefigurecalculator.py +++ b/pyrs/core/polefigurecalculator.py @@ -254,7 +254,6 @@ def calculate_pole_figure(self, det_id_list): pole_figure_array[index, 0] = alpha pole_figure_array[index, 1] = beta pole_figure_array[index, 2] = intensity_i - print ('[DB...BAT] index: {0} scan {1} alpha = {2}, beta = {3}'.format(index, scan_index, alpha, beta)) # END-FOR # END-FOR @@ -281,7 +280,6 @@ def export_pole_figure(self, detector_id_list, file_name, file_type, file_heade detector_id_list = self.get_detector_ids() else: checkdatatypes.check_list('Detector IDs', detector_id_list) - print ('[DB...DEL] detector ID list: {}'.format(detector_id_list)) # check inputs checkdatatypes.check_file_name(file_name, check_exist=False, check_writable=True) @@ -327,7 +325,6 @@ def get_peak_fit_parameter_vec(self, param_name, det_id): ''.format(param_name, self._peak_fit_info_dict[det_id].keys(), self._peak_fit_info_dict[det_id][log_index].keys())) # END-FOR - # print ('[DB...BAT] Param {} Detector {}: {}'.format(param_name, det_id, param_vec)) return param_vec @@ -377,8 +374,8 @@ def get_pole_figure_vectors(self, det_id, max_cost, min_cost=1.): taken_index_list.append(idx) # END-IF - print ('[DB...BAT] detector: {} has total {} peaks; {} are selected due to cost < {}.' - ''.format(det_id, len(cost_vec), len(taken_index_list), max_cost)) + # print ('[DB...BAT] detector: {} has total {} peaks; {} are selected due to cost < {}.' + # ''.format(det_id, len(cost_vec), len(taken_index_list), max_cost)) selected_log_index_vec = numpy.take(log_index_vec, taken_index_list, axis=0) selected_pole_figure_vec = numpy.take(pole_figure_vec, taken_index_list, axis=0) @@ -482,21 +479,6 @@ def reset_calculator(self): # END-OF-CLASS (PoleFigureCalculator) -def test_rotate(): - pf_cal = PoleFigureCalculator() - pf_cal._use_matmul = True - - - # row 636: same from pyrs-gui-test - two_theta = 82.3940 - omega = -48.805 - chi = 8.992663 - phi = 60.00 - - a, b = pf_cal.rotate_project_q(two_theta, omega, chi, phi) - print (a, b) - - def export_arrays_to_ascii(pole_figure_array_dict, detector_id_list, file_name): """ export a dictionary of arrays to an ASCII file @@ -509,7 +491,7 @@ def export_arrays_to_ascii(pole_figure_array_dict, detector_id_list, file_name): checkdatatypes.check_dict('Pole figure array dictionary', pole_figure_array_dict) checkdatatypes.check_list('Detector ID list', detector_id_list) - print ('[DB...Export Pole Figure Arrays To ASCII:\nKeys: {0}\nValues[0]: {1}' + print ('[INFO] Export Pole Figure Arrays To ASCII:\nKeys: {0}\nValues[0]: {1}' ''.format(pole_figure_array_dict.keys(), pole_figure_array_dict.values()[0])) # combine @@ -536,8 +518,10 @@ def export_arrays_to_ascii(pole_figure_array_dict, detector_id_list, file_name): def export_to_mtex(pole_figure_array_dict, detector_id_list, file_name, header): """ export to mtex format, which includes - line 1: header - line 2 and on: alpha\tbeta\tintensity + line 1: NRSF2 + line 2: alpha beta intensity + line 3: (optional header) + line 4 and on: alpha\tbeta\tintensity :param file_name: :param detector_id_list: selected the detector IDs for pole figure :param pole_figure_array_dict: @@ -548,18 +532,11 @@ def export_to_mtex(pole_figure_array_dict, detector_id_list, file_name, header): checkdatatypes.check_dict('Pole figure array dictionary', pole_figure_array_dict) checkdatatypes.check_list('Detector ID list', detector_id_list) - # initialize output string - mtex = '' - - # MTEX HEAD - """ - MTEX file format -L 1 |NRSF2 -L 2 |alpha beta intensity - """ - # TODO - 20181204 - Implement head #36 - ASAP(3) + # initialize output string: MTEX HEAD + mtex = 'NRSF2\n' + mtex += 'alpha beta intensity\n' - # header + # user optional header mtex += '{0}\n'.format(header) # writing data @@ -572,9 +549,6 @@ def export_to_mtex(pole_figure_array_dict, detector_id_list, file_name, header): 'Find out how detector IDs are involved.') sample_log_index, pole_figure_array = pole_figure_array_dict[pf_key] - - print ('[DB...BAT] PF-key: {}... Array Shape: {}'.format(pf_key, pole_figure_array.shape)) - for i_pt in range(pole_figure_array.shape[0]): mtex += '{0:5.5f}\t{1:5.5f}\t{2:5.5f}\n' \ ''.format(pole_figure_array[i_pt, 0], pole_figure_array[i_pt, 1], pole_figure_array[i_pt, 2]) @@ -605,3 +579,17 @@ def does_numpy_support_matmul(): return True return False + + +def test_rotate(): + pf_cal = PoleFigureCalculator() + pf_cal._use_matmul = True + + # row 636: same from pyrs-gui-test + two_theta = 82.3940 + omega = -48.805 + chi = 8.992663 + phi = 60.00 + + a, b = pf_cal.rotate_project_q(two_theta, omega, chi, phi) + print (a, b) diff --git a/pyrs/core/reductionengine.py b/pyrs/core/reductionengine.py index 805192bb2..0c2a8da28 100644 --- a/pyrs/core/reductionengine.py +++ b/pyrs/core/reductionengine.py @@ -2,12 +2,39 @@ import os from pyrs.utilities import checkdatatypes from pyrs.utilities import hb2b_utilities + from mantid.simpleapi import FilterEvents, LoadEventNexus, LoadInstrument, GenerateEventsFilter +from mantid.simpeapi import ConvertSpectrumAxis, ResampleX, Transpose from mantid.api import AnalysisDataService as ADS from pyrs.utilities import file_utilities from pyrs.core import scandataio +def get_log_value(workspace, log_name): + """ + get log value + :param workspace: + :param log_name: + :return: + """ + # TODO - 20181204 - Implement! + + return blabla + + +def set_log_value(workspace, log_name, log_value): + """ + set a value to a workspace's sample logs + :param workspace: + :param log_name: + :param log_value: + :return: + """ + # TODO - 20181204 - Implement! + + return + + def retrieve_workspace(ws_name, must_be_event=True): """ retrieve workspace @@ -34,6 +61,13 @@ def __init__(self): """ self._curr_reduced_data = None # dict[ws name] = vec_2theta, vec_y, vec_e + # calibration manager + self._calibration_manager = hb2b_utilities.CalibrationManager() + + # number of bins + self._num_bins = 1000 + self._2theta_resolution = 0.1 + return def _convert_to_2theta(self, event_ws_name, raw_nexus_file_name): @@ -47,7 +81,7 @@ def _convert_to_2theta(self, event_ws_name, raw_nexus_file_name): if raw_nexus_file_name is not None: run_date = file_utilities.check_creation_date(raw_nexus_file_name) try: - cal_ref_id = self.calibration_manager.check_load_calibration(exp_date=run_date) + cal_ref_id = self._calibration_manager.check_load_calibration(exp_date=run_date) except RuntimeError as run_err: err_msg = 'Unable to locate calibration file for run {} due to {}\n'.format(run_date, run_err) cal_ref_id = None @@ -60,8 +94,16 @@ def _convert_to_2theta(self, event_ws_name, raw_nexus_file_name): LoadInstrument(Workspace=event_ws_name, InstrumentName='HB2B', RewriteSpectraMap=True) + ConvertSpectrumAxis(InputWorkspace=event_ws_name, Target='Theta', OutputWorkspace=event_ws_name, + EnableLogging=False) + Transpose(InputWorkspace=event_ws_name, OutputWorkspace=event_ws_name, EnableLogging=False) + + ResampleX(InputWorkspace=event_ws_name, OutputWorkspace=event_ws_name, XMin=twotheta_min, XMax=twotheta_min, + NumberBins=num_bins, EnableLogging=False) + # TODO - 20181204 - Refer to "WANDPowderReduction" - ASAP(0) + return vec_2theta, vec_y, vec_e @staticmethod @@ -102,6 +144,28 @@ def _load_event_nexus(nexus_file_name, ws_name=False): return ws_name + @staticmethod + def _set_geometry_calibration(ws_name, calibration_dict): + """ + set the calibrated geometry parameter to workspace such that + :param ws_name: + :param calibration_dict: + :return: + """ + workspace = retrieve_workspace(ws_name) + + # set 2theta 0 + two_theta = get_log_value(workspace, 'twotheta') + two_theta += calibration_dict['2theta_0'] + set_log_value(workspace, 'twotheta', two_theta) + + # shift parameters + set_log_value(workspace, 'shiftx', calibration_dict['shiftx']) + set_log_value(workspace, 'shifty', calibration_dict['shifty']) + + # spin... + # TODO - 20181204 - Refer to IDF for the rest of parameters + @staticmethod def _slice_mapping_scan(ws_name): """ @@ -299,3 +363,15 @@ def save_reduced_data(self, reduced_data_dict, file_name): scandataio.save_hb2b_reduced_data(scan_index_dict, file_name) return + + def set_2theta_resolution(self, delta_two_theta): + """ + set 2theta resolution + :param delta_two_theta: 2theta resolution + :return: + """ + checkdatatypes.check_float_variable('2-theta resolution', delta_two_theta, (1.E-10, 10.)) + + self._2theta_resolution = delta_two_theta + + return \ No newline at end of file diff --git a/pyrs/interface/gui_helper.py b/pyrs/interface/gui_helper.py index d1e670cd8..a0b56bdad 100644 --- a/pyrs/interface/gui_helper.py +++ b/pyrs/interface/gui_helper.py @@ -82,6 +82,23 @@ def browse_file(parent, caption, default_dir, file_filter, file_list=False, save return str(file_name) +def get_save_file_name(parent, dir_name, caption, file_filter): + # TODO - 20181204 - Replace getSaveFileName by a self-extended method to be fine with both Qt4 and Qt5 ASAP(1) + file_info = QFileDialog.getSaveFileName(parent, directory=dir_name, + caption=caption, + filter=file_filter) + + if isinstance(file_info, tuple): + file_name = str(file_info[0]) + file_filter = file_info[1] + print ('[DB...Save Pole Figure] File name: {0}, Filter = {1}'.format(file_name, file_filter)) + else: + file_name = str(file_info) + file_filter = None + + return file_name, file_filter + + def parse_float(float_str): """ parse flaots from a string or a LineEdit diff --git a/pyrs/interface/textureanalysiswindow.py b/pyrs/interface/textureanalysiswindow.py index 32eef9650..5214ebc44 100644 --- a/pyrs/interface/textureanalysiswindow.py +++ b/pyrs/interface/textureanalysiswindow.py @@ -500,18 +500,9 @@ def do_save_pole_figure(self): else: file_filter = 'MTEX (*.jul);;ASCII (*.dat);;All Files (*.*)' - # TODO - 20181204 - Replace getSaveFileName by a self-extended method to be fine with both Qt4 and Qt5 ASAP(1) - file_info = QFileDialog.getSaveFileName(self, directory=self._core.working_dir, - caption='Save Pole Figure To ASCII File', - filter=file_filter) - - if isinstance(file_info, tuple): - file_name = str(file_info[0]) - file_filter = file_info[1] - print ('[DB...Save Pole Figure] File name: {0}, Filter = {1}'.format(file_name, file_filter)) - else: - file_name = str(file_info) - file_filter = None + file_name = gui_helper.browse_file(self, caption='Save Pole Figure To ASCII File', + default_dir=self._core.working_dir, file_filter=file_filter, + file_list=False, save_file=True) # return/quit if action is cancelled if len(file_name) == 0: