Source code for drtsans.mono.gpsans.prepare_sensitivities_correction
import os
import h5py
import numpy as np
from drtsans.prepare_sensivities_correction import PrepareSensitivityCorrection
from drtsans.mono.spice_data import SpiceRun
from typing import List, Union
MY_BEAM_LINE = "CG2"
[docs]
def prepare_spice_sensitivities_correction(
flood_spice_runs: List[SpiceRun],
direct_beam_spice_runs: Union[List[SpiceRun], None],
moving_detectors_methods: bool,
min_count_threshold: float,
max_count_threshold: float,
nexus_dir: Union[str, None],
mask_file: Union[str, None],
masked_pixels: Union[str, None],
beam_center_mask_radius: float,
output_dir: Union[str, None],
file_suffix: str = "spice",
pixel_calibration_file: Union[str, None] = None,
solid_angle_correction: bool = True,
) -> str:
"""
Parameters
----------
flood_spice_runs: ~list
list of SpiceRun
direct_beam_spice_runs: ~list or None
list of direct beam run (i.e., transmission run) in form of SpiceRun
moving_detectors_methods: bool
flag of sensitivity preparation method: if True, it is with moving detector. otherwise, detector patch
min_count_threshold: float
minimum threshold of allowed (normalized) counts
max_count_threshold
nexus_dir
mask_file: str, None
mask file applied to data
masked_pixels: str, None
set of pixels to mask
beam_center_mask_radius: float
radius in unit (mm) of beam center to mask for transmission calculation
output_dir: str, None
output directory, None for default as /HFIR/{MY_BEAM_LINE}/shared/drt_sensitivity/
file_suffix:
pixel_calibration_file: str or None
if it is specified as a pixel calibration, include pixel calibration in the computation
solid_angle_correction: bool
do solid angle correction
"""
# Determine output directory if default
if output_dir is None:
output_dir = f"/HFIR/{MY_BEAM_LINE}/shared/drt_sensitivity/"
if not os.path.exists(output_dir):
os.mkdir(output_dir)
# Determine sensitivities file name
if pixel_calibration_file is None:
file_suffix += "_nobar"
else:
file_suffix += "_bar"
sens_file_name = os.path.join(output_dir, f"sens_gpsans_{file_suffix}.nxs")
# Create the sensitivity preparation correction workflow object
preparer = PrepareSensitivityCorrection(MY_BEAM_LINE)
# Load flood runs
# map the run number to file name as it is SPICE
flood_nexus_files = [spice_run.unique_nexus_name(nexus_dir, True) for spice_run in flood_spice_runs]
preparer.set_flood_runs(flood_nexus_files)
# Process beam center/transmission runs
if direct_beam_spice_runs is not None:
transmission_nexus_files = [
spice_run.unique_nexus_name(nexus_dir, True) for spice_run in direct_beam_spice_runs
]
preparer.set_direct_beam_runs(transmission_nexus_files)
# Set extra masks
preparer.set_masks(mask_file, masked_pixels)
# Set beam center radius
if beam_center_mask_radius is not None:
preparer.set_beam_center_radius(beam_center_mask_radius)
else:
raise RuntimeError("MASK BEAM CENTER RADIUS must be set")
# Pixel calibration
if pixel_calibration_file:
print(f"Pixel calibration: {pixel_calibration_file}")
preparer.set_pixel_calibration_flag(pixel_calibration_file)
# Solid angle
preparer.set_solid_angle_correction_flag(solid_angle_correction)
# Run: since it is for SPICE file, it is enforced to use IDF from NeXus
try:
preparer.execute(
moving_detectors_methods,
min_count_threshold,
max_count_threshold,
sens_file_name,
enforce_use_nexus_idf=True,
)
except FileNotFoundError as file_error:
raise file_error
# Information
print(f"Generated sensitivity file: {sens_file_name}")
# Load and print out some information
with h5py.File(sens_file_name) as sens:
sens_values = sens["mantid_workspace_1"]["workspace"]["values"][()]
print(f"Number of NaNs = {len(np.where(np.isnan(sens_values))[0])}")
return sens_file_name