def run_core_reduction(reduction_alg, reduction_setting_bundle): """ This function runs a core reduction. This is essentially half a reduction (either smaple or can). :param reduction_alg: a handle to the reduction algorithm. :param reduction_setting_bundle: a ReductionSettingBundle tuple :return: an OutputBundle and an OutputPartsBundle """ # Get component to reduce component = get_component_to_reduce(reduction_setting_bundle) # Set the properties on the reduction algorithms serialized_state = reduction_setting_bundle.state.property_manager reduction_alg.setProperty("SANSState", serialized_state) reduction_alg.setProperty("Component", component) reduction_alg.setProperty("ScatterWorkspace", reduction_setting_bundle.scatter_workspace) reduction_alg.setProperty( "ScatterMonitorWorkspace", reduction_setting_bundle.scatter_monitor_workspace) reduction_alg.setProperty( "DataType", DataType.to_string(reduction_setting_bundle.data_type)) if reduction_setting_bundle.transmission_workspace is not None: reduction_alg.setProperty( "TransmissionWorkspace", reduction_setting_bundle.transmission_workspace) if reduction_setting_bundle.direct_workspace is not None: reduction_alg.setProperty("DirectWorkspace", reduction_setting_bundle.direct_workspace) reduction_alg.setProperty("OutputWorkspace", EMPTY_NAME) reduction_alg.setProperty("SumOfCounts", EMPTY_NAME) reduction_alg.setProperty("SumOfNormFactors", EMPTY_NAME) # Run the reduction core reduction_alg.execute() # Get the results output_workspace = reduction_alg.getProperty("OutputWorkspace").value output_workspace_count = reduction_alg.getProperty("SumOfCounts").value output_workspace_norm = reduction_alg.getProperty("SumOfNormFactors").value # Pull the result out of the workspace output_bundle = OutputBundle( state=reduction_setting_bundle.state, data_type=reduction_setting_bundle.data_type, reduction_mode=reduction_setting_bundle.reduction_mode, output_workspace=output_workspace) output_parts_bundle = OutputPartsBundle( state=reduction_setting_bundle.state, data_type=reduction_setting_bundle.data_type, reduction_mode=reduction_setting_bundle.reduction_mode, output_workspace_count=output_workspace_count, output_workspace_norm=output_workspace_norm) return output_bundle, output_parts_bundle
def _pack_bundles(reduction_alg, reduction_setting_bundle): output_workspaces = reduction_alg.getProperty("OutputWorkspaces").value output_workspace_counts = reduction_alg.getProperty("SumOfCounts").value output_workspace_norms = reduction_alg.getProperty( "SumOfNormFactors").value out_trans_ws = reduction_alg.getProperty( "CalculatedTransmissionWorkspaces").value out_unfit_trans_ws = reduction_alg.getProperty( "UnfittedTransmissionWorkspaces").value slices: CompletedSlices = [] for i, reduced_ws in enumerate(output_workspaces): calc_trans_ws = out_trans_ws.getItem(i) if out_trans_ws else None unfit_trans_ws = out_unfit_trans_ws.getItem( i) if out_unfit_trans_ws else None slice = ReducedSlice( wav_range=reduced_ws.getRun().getProperty( "Wavelength Range").valueAsStr, output_bundle=OutputBundle( state=reduction_setting_bundle.state, data_type=reduction_setting_bundle.data_type, reduction_mode=reduction_setting_bundle.reduction_mode, output_workspace=reduced_ws), parts_bundle=OutputPartsBundle( state=reduction_setting_bundle.state, data_type=reduction_setting_bundle.data_type, reduction_mode=reduction_setting_bundle.reduction_mode, output_workspace_count=output_workspace_counts.getItem(i), output_workspace_norm=output_workspace_norms.getItem(i)), transmission_bundle=OutputTransmissionBundle( state=reduction_setting_bundle.state, data_type=reduction_setting_bundle.data_type, calculated_transmission_workspace=calc_trans_ws, unfitted_transmission_workspace=unfit_trans_ws)) slices.append(slice) return slices
def _get_existing_cans(reduction_setting_bundle, state): output_parts = reduction_setting_bundle.output_parts reduction_mode = reduction_setting_bundle.reduction_mode data_type = reduction_setting_bundle.data_type existing_slices = [] for wav_slice in state.wavelength.wavelength_interval.selected_ranges: wav_string = wav_range_to_str(wav_slice) reduced_can_workspace, reduced_can_workspace_count, reduced_can_workspace_norm = \ get_reduced_can_workspace_from_ads(state, output_parts, reduction_mode, wav_string) output_calculated_transmission_workspace, output_unfitted_transmission_workspace = \ get_transmission_workspaces_from_ads(state, reduction_mode, wav_string) # Set the results on the output bundle existing_slices.append( ReducedSlice( wav_range=wav_string, output_bundle=OutputBundle( state=state, data_type=data_type, reduction_mode=reduction_mode, output_workspace=reduced_can_workspace), parts_bundle=OutputPartsBundle( state=state, data_type=data_type, reduction_mode=reduction_mode, output_workspace_count=reduced_can_workspace_count, output_workspace_norm=reduced_can_workspace_norm), transmission_bundle=OutputTransmissionBundle( state=reduction_setting_bundle.state, data_type=data_type, calculated_transmission_workspace= output_calculated_transmission_workspace, unfitted_transmission_workspace= output_unfitted_transmission_workspace))) return existing_slices
def run_core_event_slice_reduction(reduction_alg, reduction_setting_bundle): """ This function runs a core reduction for event slice data. This reduction slices by event time and converts to q. All other operations, such as moving and converting to histogram, have been performed before the event slicing. :param reduction_alg: a handle to the reduction algorithm. :param reduction_setting_bundle: a ReductionSettingBundle tuple :return: an OutputBundle and an OutputPartsBundle """ # Get component to reduce component = get_component_to_reduce(reduction_setting_bundle) # Set the properties on the reduction algorithms serialized_state = Serializer.to_json(reduction_setting_bundle.state) reduction_alg.setProperty("SANSState", serialized_state) reduction_alg.setProperty("Component", component) reduction_alg.setProperty("ScatterWorkspace", reduction_setting_bundle.scatter_workspace) reduction_alg.setProperty("DirectWorkspace", reduction_setting_bundle.direct_workspace) reduction_alg.setProperty("TransmissionWorkspace", reduction_setting_bundle.transmission_workspace) reduction_alg.setProperty("DummyMaskWorkspace", reduction_setting_bundle.dummy_mask_workspace) reduction_alg.setProperty( "ScatterMonitorWorkspace", reduction_setting_bundle.scatter_monitor_workspace) reduction_alg.setProperty("DataType", reduction_setting_bundle.data_type.value) reduction_alg.setProperty("OutputWorkspace", EMPTY_NAME) reduction_alg.setProperty("SumOfCounts", EMPTY_NAME) reduction_alg.setProperty("SumOfNormFactors", EMPTY_NAME) # Run the reduction core reduction_alg.execute() # Get the results output_workspace = reduction_alg.getProperty("OutputWorkspace").value output_workspace_count = reduction_alg.getProperty("SumOfCounts").value output_workspace_norm = reduction_alg.getProperty("SumOfNormFactors").value output_calculated_transmission_workspace = reduction_alg.getProperty( "CalculatedTransmissionWorkspace").value output_unfitted_transmission_workspace = reduction_alg.getProperty( "UnfittedTransmissionWorkspace").value # Pull the result out of the workspace output_bundle = OutputBundle( state=reduction_setting_bundle.state, data_type=reduction_setting_bundle.data_type, reduction_mode=reduction_setting_bundle.reduction_mode, output_workspace=output_workspace) output_parts_bundle = OutputPartsBundle( state=reduction_setting_bundle.state, data_type=reduction_setting_bundle.data_type, reduction_mode=reduction_setting_bundle.reduction_mode, output_workspace_count=output_workspace_count, output_workspace_norm=output_workspace_norm) output_transmission_bundle = OutputTransmissionBundle( state=reduction_setting_bundle.state, data_type=reduction_setting_bundle.data_type, calculated_transmission_workspace= output_calculated_transmission_workspace, unfitted_transmission_workspace=output_unfitted_transmission_workspace, ) return output_bundle, output_parts_bundle, output_transmission_bundle
def run_optimized_for_can(reduction_alg, reduction_setting_bundle, event_slice_optimisation=False): """ Check if the state can reduction already exists, and if so, use it else reduce it and add it to the ADS. :param reduction_alg: a handle to the SANSReductionCore algorithm :param reduction_setting_bundle: a ReductionSettingBundle tuple. :param event_slice_optimisation: An optional bool. If true then run run_core_event_slice_reduction, else run_core_reduction. :return: a reduced workspace, a partial output workspace for the counts, a partial workspace for the normalization. """ state = reduction_setting_bundle.state output_parts = reduction_setting_bundle.output_parts reduction_mode = reduction_setting_bundle.reduction_mode data_type = reduction_setting_bundle.data_type reduced_can_workspace, reduced_can_workspace_count, reduced_can_workspace_norm = \ get_reduced_can_workspace_from_ads(state, output_parts, reduction_mode) output_calculated_transmission_workspace, output_unfitted_transmission_workspace = \ get_transmission_workspaces_from_ads(state, reduction_mode) # Set the results on the output bundle output_bundle = OutputBundle(state=state, data_type=data_type, reduction_mode=reduction_mode, output_workspace=reduced_can_workspace) output_parts_bundle = OutputPartsBundle( state=state, data_type=data_type, reduction_mode=reduction_mode, output_workspace_count=reduced_can_workspace_count, output_workspace_norm=reduced_can_workspace_norm) output_transmission_bundle = OutputTransmissionBundle( state=reduction_setting_bundle.state, data_type=data_type, calculated_transmission_workspace= output_calculated_transmission_workspace, unfitted_transmission_workspace=output_unfitted_transmission_workspace) # The logic table for the recalculation of the partial outputs is: # | output_parts | reduced_can_workspace_count is None | reduced_can_workspace_norm is None | Recalculate | # ---------------------------------------------------------------------------------------------------------- # | False | True | True | False | # | False | True | False | False | # | False | False | True | False | # | False | False | False | False | # | True | True | True | False | # | True | True | False | True | # | True | False | True | True | # | True | False | False | False | is_invalid_partial_workspaces = ( (output_parts_bundle.output_workspace_count is None and output_parts_bundle.output_workspace_norm is not None) or (output_parts_bundle.output_workspace_count is not None and output_parts_bundle.output_workspace_norm is None)) is_invalid_transmission_workspaces = ( output_transmission_bundle.calculated_transmission_workspace is None or output_transmission_bundle.unfitted_transmission_workspace is None) partial_output_require_reload = output_parts and is_invalid_partial_workspaces must_reload = output_bundle.output_workspace is None or partial_output_require_reload or is_invalid_transmission_workspaces if 'boost.mpi' in sys.modules: # In MPI runs the result is only present on rank 0 (result of Q1D2 integration), # so the reload flag must be broadcasted from rank 0. must_reload = mpisetup.boost.mpi.broadcast(mpisetup.boost.mpi.world, must_reload, 0) if must_reload: # if output_bundle.output_workspace is None or partial_output_require_reload: if not event_slice_optimisation: output_bundle, output_parts_bundle, \ output_transmission_bundle = run_core_reduction(reduction_alg, reduction_setting_bundle) else: output_bundle, output_parts_bundle, \ output_transmission_bundle = run_core_event_slice_reduction(reduction_alg, reduction_setting_bundle) # Now we need to tag the workspaces and add it to the ADS if output_bundle.output_workspace is not None: write_hash_into_reduced_can_workspace( state=output_bundle.state, workspace=output_bundle.output_workspace, partial_type=None, reduction_mode=reduction_mode) if output_transmission_bundle.calculated_transmission_workspace is not None and \ output_transmission_bundle.unfitted_transmission_workspace is not None: write_hash_into_reduced_can_workspace( state=output_transmission_bundle.state, workspace=output_transmission_bundle. calculated_transmission_workspace, partial_type=TransmissionType.CALCULATED, reduction_mode=reduction_mode) write_hash_into_reduced_can_workspace( state=output_transmission_bundle.state, workspace=output_transmission_bundle. unfitted_transmission_workspace, partial_type=TransmissionType.UNFITTED, reduction_mode=reduction_mode) if (output_parts_bundle.output_workspace_count is not None and output_parts_bundle.output_workspace_norm is not None): write_hash_into_reduced_can_workspace( state=output_parts_bundle.state, workspace=output_parts_bundle.output_workspace_count, partial_type=OutputParts.COUNT, reduction_mode=reduction_mode) write_hash_into_reduced_can_workspace( state=output_parts_bundle.state, workspace=output_parts_bundle.output_workspace_norm, partial_type=OutputParts.NORM, reduction_mode=reduction_mode) return output_bundle, output_parts_bundle, output_transmission_bundle
def run_optimized_for_can(reduction_alg, reduction_setting_bundle): """ Check if the state can reduction already exists, and if so, use it else reduce it and add it to the ADS. @param reduction_alg: a handle to the SANSReductionCore algorithm @param reduction_setting_bundle: a ReductionSettingBundle tuple. @return: a reduced workspace, a partial output workspace for the counts, a partial workspace for the normalization. """ state = reduction_setting_bundle.state output_parts = reduction_setting_bundle.output_parts reduction_mode = reduction_setting_bundle.reduction_mode data_type = reduction_setting_bundle.data_type reduced_can_workspace, reduced_can_workspace_count, reduced_can_workspace_norm = \ get_reduced_can_workspace_from_ads(state, output_parts, reduction_mode) # Set the results on the output bundle output_bundle = OutputBundle(state=state, data_type=data_type, reduction_mode=reduction_mode, output_workspace=reduced_can_workspace) output_parts_bundle = OutputPartsBundle(state=state, data_type=data_type, reduction_mode=reduction_mode, output_workspace_count=reduced_can_workspace_count, output_workspace_norm=reduced_can_workspace_norm) # The logic table for the recalculation of the partial outputs is: # | output_parts | reduced_can_workspace_count is None | reduced_can_workspace_norm is None | Recalculate | # ---------------------------------------------------------------------------------------------------------- # | False | True | True | False | # | False | True | False | False | # | False | False | True | False | # | False | False | False | False | # | True | True | True | False | # | True | True | False | True | # | True | False | True | True | # | True | False | False | False | is_invalid_partial_workspaces = ((output_parts_bundle.output_workspace_count is None and output_parts_bundle.output_workspace_norm is not None) or (output_parts_bundle.output_workspace_count is not None and output_parts_bundle.output_workspace_norm is None)) partial_output_require_reload = output_parts and is_invalid_partial_workspaces if output_bundle.output_workspace is None or partial_output_require_reload: output_bundle, output_parts_bundle = run_core_reduction(reduction_alg, reduction_setting_bundle) # Now we need to tag the workspaces and add it to the ADS if output_bundle.output_workspace is not None: write_hash_into_reduced_can_workspace(state=output_bundle.state, workspace=output_bundle.output_workspace, partial_type=None, reduction_mode=reduction_mode) if (output_parts_bundle.output_workspace_count is not None and output_parts_bundle.output_workspace_norm is not None): write_hash_into_reduced_can_workspace(state=output_parts_bundle.state, workspace=output_parts_bundle.output_workspace_count, partial_type=OutputParts.Count, reduction_mode=reduction_mode) write_hash_into_reduced_can_workspace(state=output_parts_bundle.state, workspace=output_parts_bundle.output_workspace_norm, partial_type=OutputParts.Norm, reduction_mode=reduction_mode) return output_bundle, output_parts_bundle