def create_masker(state, detector_type): """ Provides the appropriate masker. :param state: a SANSState object :param detector_type: either HAB or LAB :return: the corresponding slicer """ data_info = state.data instrument = data_info.instrument # TODO remove this shim if instrument is SANSInstrument.LARMOR or instrument is SANSInstrument.LOQ or\ instrument is SANSInstrument.SANS2D or instrument is SANSInstrument.ZOOM: # noqa run_number = data_info.sample_scatter_run_number file_name = data_info.sample_scatter _, ipf_path = get_instrument_paths_for_sans_file(file_name) spectra_block = SpectraBlock(ipf_path, run_number, instrument, detector_type) masker = MaskerISIS(spectra_block) else: masker = NullMasker() NotImplementedError( "create_masker: Other instruments are not implemented yet.") return masker
def reset_to_defaults_for_instrument(self, file_information = None): r_range = {} instrument = None if file_information: instrument_file_path = get_instrument_paths_for_sans_file(file_information=file_information) r_range = get_named_elements_from_ipf_file(instrument_file_path[1], ["beam_centre_radius_min", "beam_centre_radius_max"], float) instrument = file_information.get_instrument() self._max_iterations = 10 self._r_min = r_range["beam_centre_radius_min"] if "beam_centre_radius_min" in r_range else 60 self._r_max = r_range["beam_centre_radius_max"] if "beam_centre_radius_max" in r_range else 280 self._left_right = True self._up_down = True self._tolerance = 0.0001251 self._lab_pos_1 = '' self._lab_pos_2 = '' self._hab_pos_2 = '' self._hab_pos_1 = '' self.scale_1 = 1000 self.scale_2 = 1000 self.COM = False self.verbose = False self.q_min = 0.01 self.q_max = 0.1 self._component = DetectorType.LAB self.update_lab = True self.update_hab = True if instrument == SANSInstrument.LARMOR: self.scale_1 = 1.0
def setup_idf_and_ipf_content(move_info, data_info): # Get the IDF and IPF path since they contain most of the import information file_name = data_info.sample_scatter idf_path, ipf_path = get_instrument_paths_for_sans_file(file_name) # Set the detector names set_detector_names(move_info, ipf_path) # Set the monitor names set_monitor_names(move_info, idf_path)
def test_that_finds_idf_and_ipf_paths(self): # Arrange file_name = "SANS2D00022024" # Act idf_path, ipf_path = get_instrument_paths_for_sans_file(file_name) # Assert self.assertTrue(idf_path is not None) self.assertTrue(ipf_path is not None) self.assertTrue("Definition" in idf_path) self.assertTrue("Parameters" in ipf_path)
def set_default_incident_monitor(normalize_monitor_info, data_info): """ The default incident monitor is stored on the IPF. :param normalize_monitor_info: a StateNormalizeMonitor object on which we set the default value :param data_info: a StateData object """ file_name = data_info.sample_scatter _, ipf_path = get_instrument_paths_for_sans_file(file_name) named_element = "default-incident-monitor-spectrum" monitor_spectrum_tag_to_search = [named_element] found_monitor_spectrum = get_named_elements_from_ipf_file(ipf_path, monitor_spectrum_tag_to_search, int) if named_element in found_monitor_spectrum: normalize_monitor_info.incident_monitor = found_monitor_spectrum[named_element]
def get_detector_size_from_sans_file(state, detector): instrument_file = get_instrument_paths_for_sans_file(state.data.sample_scatter) if detector == DetectorType.HAB: x_dim = get_named_elements_from_ipf_file(instrument_file[1], "high-angle-detector-num-columns", float)['high-angle-detector-num-columns'] y_dim = get_named_elements_from_ipf_file(instrument_file[1], "high-angle-detector-num-rows", float)['high-angle-detector-num-rows'] else: x_dim = get_named_elements_from_ipf_file(instrument_file[1], "low-angle-detector-num-columns", float)[ 'low-angle-detector-num-columns'] y_dim = get_named_elements_from_ipf_file(instrument_file[1], "low-angle-detector-num-rows", float)[ 'low-angle-detector-num-rows'] return x_dim, y_dim
def test_that_monitors_can_be_found_v2(self): # Arrange test_file = "LOQ74044" file_information_factory = SANSFileInformationFactory() file_information = file_information_factory.create_sans_file_information(test_file) full_file_path = file_information.get_file_name() idf, _ = get_instrument_paths_for_sans_file(full_file_path) # Act results = get_monitor_names_from_idf_file(idf) # Assert self.assertTrue(len(results) == 2) for key, value in list(results.items()): self.assertTrue(value == ("monitor"+str(key)))
def set_default_monitors(calculate_transmission_info, data_info): """ The default incident monitor is stored on the IPF. :param calculate_transmission_info: a StateCalculateTransmission object on which we set the default value :param data_info: a StateData object """ file_name = data_info.sample_scatter _, ipf_path = get_instrument_paths_for_sans_file(file_name) incident_tag = "default-incident-monitor-spectrum" transmission_tag = "default-transmission-monitor-spectrum" monitors_to_search = [incident_tag, transmission_tag] found_monitor_spectrum = get_named_elements_from_ipf_file(ipf_path, monitors_to_search, int) if incident_tag in found_monitor_spectrum: calculate_transmission_info.default_incident_monitor = found_monitor_spectrum[incident_tag] if transmission_tag in found_monitor_spectrum: calculate_transmission_info.default_transmission_monitor = found_monitor_spectrum[transmission_tag]
def test_that_monitors_can_be_found_v2(self): # Arrange test_file = "LOQ74044" file_information_factory = SANSFileInformationFactory() file_information = file_information_factory.create_sans_file_information(test_file) full_file_path = file_information.get_file_name() idf, _ = get_instrument_paths_for_sans_file(full_file_path) # Act results = get_monitor_names_from_idf_file(idf) # Assert self.assertTrue(len(results) == 2) for key, value in results.items(): self.assertTrue(value == ("monitor"+str(key)))
def get_position_steps(self, state): instrument_file = get_instrument_paths_for_sans_file(state.data.sample_scatter) position_1_step = get_named_elements_from_ipf_file( instrument_file[1], ["centre-finder-step-size"], float)['centre-finder-step-size'] try: position_2_step = get_named_elements_from_ipf_file( instrument_file[1], ["centre-finder-step-size2"], float)['centre-finder-step-size2'] except: position_2_step = position_1_step find_direction = self.getProperty("Direction").value if find_direction == FindDirectionEnum.LEFT_RIGHT.value: position_2_step = 0.0 elif find_direction == FindDirectionEnum.UP_DOWN.value: position_1_step = 0.0 return position_1_step, position_2_step
def test_that_named_entries_in_instrument_parameter_file_can_be_retrieved(self): # Arrange test_file = "LARMOR00003368" file_information_factory = SANSFileInformationFactory() file_information = file_information_factory.create_sans_file_information(test_file) full_file_path = file_information.get_file_name() _, ipf = get_instrument_paths_for_sans_file(full_file_path) to_search = ["low-angle-detector-name", "high-angle-detector-short-name"] # Act results = get_named_elements_from_ipf_file(ipf, to_search, str) # Assert self.assertTrue(len(results) == 2) self.assertTrue(results["low-angle-detector-name"] == "DetectorBench") self.assertTrue(results["high-angle-detector-short-name"] == "front")
def setup_detectors_from_ipf(reduction_info, data_info): file_name = data_info.sample_scatter _, ipf_path = get_instrument_paths_for_sans_file(file_name) detector_names = {DetectorType.to_string(DetectorType.LAB): "low-angle-detector-name", DetectorType.to_string(DetectorType.HAB): "high-angle-detector-name"} names_to_search = [] names_to_search.extend(detector_names.values()) found_detector_names = get_named_elements_from_ipf_file(ipf_path, names_to_search, str) for detector_type in reduction_info.detector_names.keys(): try: detector_name_tag = detector_names[detector_type] detector_name = found_detector_names[detector_name_tag] except KeyError: continue reduction_info.detector_names[detector_type] = detector_name
def create_masker(state, detector_type): """ Provides the appropriate masker. :param state: a SANSState object :param detector_type: either HAB or LAB :return: the corresponding slicer """ data_info = state.data instrument = data_info.instrument if instrument is SANSInstrument.LARMOR or instrument is SANSInstrument.LOQ or\ instrument is SANSInstrument.SANS2D or instrument is SANSInstrument.ZOOM: # noqa run_number = data_info.sample_scatter_run_number file_name = data_info.sample_scatter _, ipf_path = get_instrument_paths_for_sans_file(file_name) spectra_block = SpectraBlock(ipf_path, run_number, instrument, detector_type) masker = MaskerISIS(spectra_block, instrument) else: masker = NullMasker() NotImplementedError("MaskFactory: Other instruments are not implemented yet.") return masker
def reset_to_defaults_for_instrument(self, file_information=None): r_range = {} instrument = None if file_information: instrument_file_path = get_instrument_paths_for_sans_file( file_information=file_information) r_range = get_named_elements_from_ipf_file( instrument_file_path[1], ["beam_centre_radius_min", "beam_centre_radius_max"], float) instrument = file_information.get_instrument() self._max_iterations = 10 self._r_min = r_range[ "beam_centre_radius_min"] if "beam_centre_radius_min" in r_range else 60 self._r_max = r_range[ "beam_centre_radius_max"] if "beam_centre_radius_max" in r_range else 280 self._left_right = True self._up_down = True self._tolerance = 0.0001251 self._lab_pos_1 = '' self._lab_pos_2 = '' self._hab_pos_2 = '' self._hab_pos_1 = '' self.scale_1 = 1000 self.scale_2 = 1000 self.COM = False self.verbose = False self.q_min = 0.01 self.q_max = 0.1 self._component = DetectorType.LAB self.update_lab = True self.update_hab = True if instrument == SANSInstrument.LARMOR: self.scale_1 = 1.0
def PyExec(self): state = self._get_state() state_serialized = state.property_manager logger = Logger("CentreFinder") logger.notice("Starting centre finder routine...") progress = self._get_progress() self.scale_1 = 1000 self.scale_2 = 1000 verbose = self.getProperty('Verbose').value x_start = self.getProperty("Position1Start").value y_start = self.getProperty("Position2Start").value sample_scatter = self._get_cloned_workspace("SampleScatterWorkspace") sample_scatter_monitor = self._get_cloned_workspace( "SampleScatterMonitorWorkspace") sample_transmission = self._get_cloned_workspace( "SampleTransmissionWorkspace") sample_direct = self._get_cloned_workspace("SampleDirectWorkspace") instrument = sample_scatter.getInstrument() if instrument.getName() == 'LARMOR': self.scale_1 = 1.0 can_scatter = self._get_cloned_workspace("CanScatterWorkspace") can_scatter_monitor = self._get_cloned_workspace( "CanScatterMonitorWorkspace") can_transmission = self._get_cloned_workspace( "CanTransmissionWorkspace") can_direct = self._get_cloned_workspace("CanDirectWorkspace") component = self.getProperty("Component").value tolerance = self.getProperty("Tolerance").value max_iterations = self.getProperty("Iterations").value r_min = self.getProperty("RMin").value r_max = self.getProperty("RMax").value instrument_file = get_instrument_paths_for_sans_file( state.data.sample_scatter) position_1_step = get_named_elements_from_ipf_file( instrument_file[1], "centre-finder-step-size", float)['centre-finder-step-size'] try: position_2_step = get_named_elements_from_ipf_file( instrument_file[1], "centre-finder-step-size2", float)['centre-finder-step-size2'] except: position_2_step = position_1_step find_direction = self.getProperty("Direction").value if find_direction == FindDirectionEnum.to_string( FindDirectionEnum.Left_Right): position_2_step = 0.0 elif find_direction == FindDirectionEnum.to_string( FindDirectionEnum.Up_Down): position_1_step = 0.0 centre1 = x_start centre2 = y_start residueLR = [] residueTB = [] centre_1_hold = x_start centre_2_hold = y_start for j in range(0, max_iterations + 1): if (j != 0): centre1 += position_1_step centre2 += position_2_step progress.report("Reducing ... Pos1 " + str(centre1) + " Pos2 " + str(centre2)) sample_quartiles = self._run_quartile_reduction( sample_scatter, sample_transmission, sample_direct, "Sample", sample_scatter_monitor, component, state_serialized, centre1, centre2, r_min, r_max) if can_scatter: can_quartiles = self._run_quartile_reduction( can_scatter, can_transmission, can_direct, "Can", can_scatter_monitor, component, state_serialized, centre1, centre2, r_min, r_max) for key in sample_quartiles: sample_quartiles[key] = perform_can_subtraction( sample_quartiles[key], can_quartiles[key], self) if mantidplot: output_workspaces = self._publish_to_ADS(sample_quartiles) if verbose: self._rename_and_group_workspaces(j, output_workspaces) residueLR.append( self._calculate_residuals( sample_quartiles[MaskingQuadrant.Left], sample_quartiles[MaskingQuadrant.Right])) residueTB.append( self._calculate_residuals( sample_quartiles[MaskingQuadrant.Top], sample_quartiles[MaskingQuadrant.Bottom])) if (j == 0): logger.notice("Itr " + str(j) + ": (" + str(self.scale_1 * centre1) + ", " + str(self.scale_2 * centre2) + ") SX=" + str(residueLR[j]) + " SY=" + str(residueTB[j])) if mantidplot: self._plot_quartiles(output_workspaces, state.data.sample_scatter) else: # have we stepped across the y-axis that goes through the beam center? if residueLR[j] > residueLR[j - 1]: # yes with stepped across the middle, reverse direction and half the step size position_1_step = -position_1_step / 2 if residueTB[j] > residueTB[j - 1]: position_2_step = -position_2_step / 2 logger.notice("Itr " + str(j) + ": (" + str(self.scale_1 * centre1) + ", " + str(self.scale_2 * centre2) + ") SX=" + str(residueLR[j]) + " SY=" + str(residueTB[j])) if (residueLR[j] + residueTB[j]) < ( residueLR[j - 1] + residueTB[j - 1] ) or state.compatibility.use_compatibility_mode: centre_1_hold = centre1 centre_2_hold = centre2 if abs(position_1_step) < tolerance and abs( position_2_step) < tolerance: # this is the success criteria, we've close enough to the center logger.notice( "Converged - check if stuck in local minimum! ") break if j == max_iterations: logger.notice( "Out of iterations, new coordinates may not be the best") self.setProperty("Centre1", centre_1_hold) self.setProperty("Centre2", centre_2_hold) logger.notice("Centre coordinates updated: [{}, {}]".format( centre_1_hold * self.scale_1, centre_2_hold * self.scale_2))
def PyExec(self): state = self._get_state() state_serialized = state.property_manager logger = Logger("CentreFinder") logger.notice("Starting centre finder routine...") progress = self._get_progress() self.scale_1 = 1000 self.scale_2 = 1000 verbose = self.getProperty('Verbose').value x_start = self.getProperty("Position1Start").value y_start = self.getProperty("Position2Start").value sample_scatter = self._get_cloned_workspace("SampleScatterWorkspace") sample_scatter_monitor = self._get_cloned_workspace("SampleScatterMonitorWorkspace") sample_transmission = self._get_cloned_workspace("SampleTransmissionWorkspace") sample_direct = self._get_cloned_workspace("SampleDirectWorkspace") instrument = sample_scatter.getInstrument() if instrument.getName() == 'LARMOR': self.scale_1 = 1.0 can_scatter = self._get_cloned_workspace("CanScatterWorkspace") can_scatter_monitor = self._get_cloned_workspace("CanScatterMonitorWorkspace") can_transmission = self._get_cloned_workspace("CanTransmissionWorkspace") can_direct = self._get_cloned_workspace("CanDirectWorkspace") component = self.getProperty("Component").value tolerance = self.getProperty("Tolerance").value max_iterations = self.getProperty("Iterations").value r_min = self.getProperty("RMin").value r_max = self.getProperty("RMax").value instrument_file = get_instrument_paths_for_sans_file(state.data.sample_scatter) position_1_step = get_named_elements_from_ipf_file( instrument_file[1], ["centre-finder-step-size"], float)['centre-finder-step-size'] try: position_2_step = get_named_elements_from_ipf_file( instrument_file[1], ["centre-finder-step-size2"], float)['centre-finder-step-size2'] except: position_2_step = position_1_step find_direction = self.getProperty("Direction").value if find_direction == FindDirectionEnum.to_string(FindDirectionEnum.Left_Right): position_2_step = 0.0 elif find_direction == FindDirectionEnum.to_string(FindDirectionEnum.Up_Down): position_1_step = 0.0 centre1 = x_start centre2 = y_start residueLR = [] residueTB = [] centre_1_hold = x_start centre_2_hold = y_start for j in range(0, max_iterations + 1): if(j != 0): centre1 += position_1_step centre2 += position_2_step progress.report("Reducing ... Pos1 " + str(centre1) + " Pos2 " + str(centre2)) sample_quartiles = self._run_quartile_reduction(sample_scatter, sample_transmission, sample_direct, "Sample", sample_scatter_monitor, component, state_serialized, centre1, centre2, r_min, r_max) if can_scatter: can_quartiles = self._run_quartile_reduction(can_scatter, can_transmission, can_direct, "Can", can_scatter_monitor, component, state_serialized, centre1, centre2, r_min, r_max) for key in sample_quartiles: sample_quartiles[key] = perform_can_subtraction(sample_quartiles[key], can_quartiles[key], self) if mantidplot: output_workspaces = self._publish_to_ADS(sample_quartiles) if verbose: self._rename_and_group_workspaces(j, output_workspaces) residueLR.append(self._calculate_residuals(sample_quartiles[MaskingQuadrant.Left], sample_quartiles[MaskingQuadrant.Right])) residueTB.append(self._calculate_residuals(sample_quartiles[MaskingQuadrant.Top], sample_quartiles[MaskingQuadrant.Bottom])) if(j == 0): logger.notice("Itr {0}: ( {1}, {2} ) SX={3:.5g} SY={4:.5g}". format(j, self.scale_1 * centre1, self.scale_2 * centre2, residueLR[j], residueTB[j])) if mantidplot: self._plot_quartiles(output_workspaces, state.data.sample_scatter) else: # have we stepped across the y-axis that goes through the beam center? if residueLR[j] > residueLR[j-1]: # yes with stepped across the middle, reverse direction and half the step size position_1_step = - position_1_step / 2 if residueTB[j] > residueTB[j-1]: position_2_step = - position_2_step / 2 logger.notice("Itr {0}: ( {1}, {2} ) SX={3:.5g} SY={4:.5g}". format(j, self.scale_1 * centre1, self.scale_2 * centre2, residueLR[j], residueTB[j])) if (residueLR[j]+residueTB[j]) < (residueLR[j-1]+residueTB[j-1]) or state.compatibility.use_compatibility_mode: centre_1_hold = centre1 centre_2_hold = centre2 if abs(position_1_step) < tolerance and abs(position_2_step) < tolerance: # this is the success criteria, we've close enough to the center logger.notice("Converged - check if stuck in local minimum! ") break if j == max_iterations: logger.notice("Out of iterations, new coordinates may not be the best") self.setProperty("Centre1", centre_1_hold) self.setProperty("Centre2", centre_2_hold) logger.notice("Centre coordinates updated: [{}, {}]".format(centre_1_hold*self.scale_1, centre_2_hold*self.scale_2))