Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6597ca22d1 | |||
| ce31dcb190 | |||
| 41c5218413 | |||
| 8abd977656 | |||
| 432d85c9b3 | |||
| c222f42a89 | |||
| fbced41b9f |
@@ -2,5 +2,5 @@
|
||||
Package to handle data redction at AMOR instrument to be used by __main__.py script.
|
||||
"""
|
||||
|
||||
__version__ = '3.0.4'
|
||||
__date__ = '2025-11-04'
|
||||
__version__ = '3.0.7'
|
||||
__date__ = '2025-12-01'
|
||||
|
||||
@@ -25,8 +25,15 @@ class ExtractWalltime(EventDataAction):
|
||||
dataset.data.events = new_events
|
||||
|
||||
class MergeFrames(EventDataAction):
|
||||
def __init__(self, lamdaCut=None):
|
||||
self.lamdaCut=lamdaCut
|
||||
|
||||
def perform_action(self, dataset: EventDatasetProtocol)->None:
|
||||
tofCut = const.lamdaCut*dataset.geometry.chopperDetectorDistance/const.hdm*1e-13
|
||||
if self.lamdaCut is None:
|
||||
lamdaCut = const.lamdaCut
|
||||
else:
|
||||
lamdaCut = self.lamdaCut
|
||||
tofCut = lamdaCut*dataset.geometry.chopperDetectorDistance/const.hdm*1e-13
|
||||
total_offset = (tofCut +
|
||||
dataset.timing.tau * (dataset.timing.ch1TriggerPhase + dataset.timing.chopperPhase/2)/180)
|
||||
dataset.data.events.tof = merge_frames(dataset.data.events.tof, tofCut, dataset.timing.tau, total_offset)
|
||||
|
||||
@@ -84,7 +84,7 @@ class AmorHeader:
|
||||
user_orcid = None
|
||||
sampleName = self.hdf['entry1/sample/name'][0].decode('utf-8')
|
||||
model = self.hdf['entry1/sample/model'][0].decode('utf-8')
|
||||
if 'stack:' in model:
|
||||
if 'stack' in model:
|
||||
import yaml
|
||||
model = yaml.safe_load(model)
|
||||
else:
|
||||
@@ -223,7 +223,6 @@ class AmorEventData(AmorHeader):
|
||||
|
||||
def __init__(self, fileName:Union[str, h5py.File, BinaryIO], first_index:int=0, max_events:int=100_000_000):
|
||||
if type(fileName) is str:
|
||||
#logging.warning(f' opening file {fileName}')
|
||||
logging.warning(f' {fileName.split("/")[-1]}')
|
||||
self.file_list = [fileName]
|
||||
hdf = h5py.File(fileName, 'r', swmr=True)
|
||||
|
||||
@@ -65,9 +65,14 @@ class LZGrid:
|
||||
def qzRange(self):
|
||||
return self._qzRange
|
||||
|
||||
def __init__(self, qResolution, qzRange):
|
||||
def __init__(self, qResolution, qzRange, lambda_overwrite=None):
|
||||
self._qResolution = qResolution
|
||||
self._qzRange = qzRange
|
||||
if lambda_overwrite is None:
|
||||
self.lamdaMax = const.lamdaMax
|
||||
self.lamdaCut = const.lamdaCut
|
||||
else:
|
||||
self.lamdaCut, self.lamdaMax = lambda_overwrite
|
||||
|
||||
@property
|
||||
@cache
|
||||
@@ -92,8 +97,8 @@ class LZGrid:
|
||||
|
||||
@cache
|
||||
def lamda(self):
|
||||
lamdaMax = 16
|
||||
lamdaMin = const.lamdaCut
|
||||
lamdaMax = self.lamdaMax
|
||||
lamdaMin = self.lamdaCut
|
||||
lamda_grid = lamdaMin*(1+self.dldl)**np.arange(int(np.log(lamdaMax/lamdaMin)/np.log(1+self.dldl)+1))
|
||||
return lamda_grid
|
||||
|
||||
|
||||
@@ -85,12 +85,19 @@ class ProjectedReflectivity:
|
||||
self.R -= R
|
||||
self.dR = np.sqrt(self.dR**2+dR**2)
|
||||
|
||||
def plot(self, **kwargs):
|
||||
from matplotlib import pyplot as plt
|
||||
plt.errorbar(self.Q, self.R, yerr=self.dR, **kwargs)
|
||||
plt.yscale('log')
|
||||
plt.xlabel('Q / Å$^{-1}$')
|
||||
plt.ylabel('R')
|
||||
|
||||
class LZProjection(ProjectionInterface):
|
||||
grid: LZGrid
|
||||
lamda: np.ndarray
|
||||
alphaF: np.ndarray
|
||||
is_normalized: bool
|
||||
angle: float
|
||||
|
||||
data: np.recarray
|
||||
_dtype = np.dtype([
|
||||
@@ -107,6 +114,7 @@ class LZProjection(ProjectionInterface):
|
||||
def __init__(self, tthh: float, grid: LZGrid):
|
||||
self.grid = grid
|
||||
self.is_normalized = False
|
||||
self.angle = tthh
|
||||
|
||||
alphaF_z = tthh + Detector.delta_z
|
||||
lamda_l = self.grid.lamda()
|
||||
@@ -206,12 +214,14 @@ class LZProjection(ProjectionInterface):
|
||||
Normalize the dataaset and take into account a difference in
|
||||
detector angle for measurement and reference.
|
||||
"""
|
||||
logging.debug(f' correcting for incident angle difference from norm {norm.angle} to data {self.angle}')
|
||||
norm_lz = norm.norm
|
||||
thetaN_z = Detector.delta_z+norm.angle
|
||||
thetaN_lz = np.ones_like(norm_lz)*thetaN_z
|
||||
thetaN_lz = np.where(np.absolute(thetaN_lz)>5e-3, thetaN_lz, np.nan)
|
||||
self.data.mask &= (np.absolute(thetaN_lz)>5e-3)
|
||||
ref_lz = (self.data.I*np.absolute(thetaN_lz))/(norm_lz*np.absolute(self.alphaF))
|
||||
delta_lz = np.ones_like(norm_lz)*Detector.delta_z
|
||||
# do not perform gravity correction for footprint, would require norm detector distance that is unknown here
|
||||
fp_corr_lz = np.where(np.absolute(delta_lz+norm.angle)>5e-3,
|
||||
(delta_lz+self.angle)/(delta_lz+norm.angle), np.nan)
|
||||
self.data.mask &= np.logical_not(np.isnan(fp_corr_lz))
|
||||
ref_lz = self.data.I/norm_lz/fp_corr_lz
|
||||
ref_lz *= norm.monitor/self.monitor
|
||||
ref_lz[np.logical_not(self.data.mask)] = np.nan
|
||||
self.data.norm = norm_lz
|
||||
@@ -298,7 +308,7 @@ class LZProjection(ProjectionInterface):
|
||||
plt.colorbar(label='I / cpm')
|
||||
plt.xlabel('$\\lambda$ / $\\AA$')
|
||||
plt.ylabel('$\\Theta$ / °')
|
||||
plt.xlim(3., 12.)
|
||||
plt.xlim(self.lamda[0,0], self.lamda[-1,0])
|
||||
af = self.alphaF[self.data.mask]
|
||||
plt.ylim(af.min(), af.max())
|
||||
plt.title('Wavelength vs. Reflection Angle')
|
||||
|
||||
@@ -51,6 +51,7 @@ class E2HReduction:
|
||||
self.plot_kwds = {}
|
||||
plt.rcParams.update({'font.size': self.config.reduction.fontsize})
|
||||
|
||||
self.overwrite = eh.ApplyParameterOverwrites(self.config.experiment) # some actions use instrument parameters, change before that
|
||||
if self.config.reduction.update:
|
||||
# live update implies plotting
|
||||
self.config.reduction.show_plot = True
|
||||
@@ -68,6 +69,7 @@ class E2HReduction:
|
||||
# Actions on datasets not used for normalization
|
||||
self.event_actions = eh.ApplyPhaseOffset(self.config.experiment.chopperPhaseOffset)
|
||||
if not self.config.reduction.fast:
|
||||
self.event_actions |= self.overwrite
|
||||
self.event_actions |= eh.CorrectChopperPhase()
|
||||
self.event_actions |= ea.ExtractWalltime()
|
||||
else:
|
||||
@@ -88,7 +90,7 @@ class E2HReduction:
|
||||
self.event_actions |= eh.TofTimeCorrection(self.config.experiment.incidentAngle==IncidentAngle.alphaF)
|
||||
# select needed actions in depenence of plots
|
||||
if self.config.reduction.plot in NEEDS_LAMDA or not self.config.experiment.is_default('lambdaRange'):
|
||||
self.event_actions |= ea.MergeFrames()
|
||||
self.event_actions |= ea.MergeFrames(lamdaCut=self.config.experiment.lambdaRange[0])
|
||||
self.event_actions |= ea.AnalyzePixelIDs(self.config.experiment.yRange)
|
||||
self.event_actions |= eh.TofTimeCorrection(self.config.experiment.incidentAngle==IncidentAngle.alphaF)
|
||||
self.event_actions |= ea.CalculateWavelength(self.config.experiment.lambdaRange)
|
||||
@@ -96,8 +98,8 @@ class E2HReduction:
|
||||
|
||||
# plot dependant options
|
||||
if self.config.reduction.plot in [E2HPlotSelection.All, E2HPlotSelection.LT, E2HPlotSelection.Q]:
|
||||
self.grid = LZGrid(0.05, [0.0, 0.25])
|
||||
self.grid.dldl = 0.05
|
||||
self.grid = LZGrid(0.05, [0.0, 0.25], lambda_overwrite=self.config.experiment.lambdaRange)
|
||||
self.grid.dldl = 0.01
|
||||
|
||||
if self.config.reduction.plot in [E2HPlotSelection.All, E2HPlotSelection.Raw,
|
||||
E2HPlotSelection.LT, E2HPlotSelection.YT,
|
||||
@@ -151,6 +153,7 @@ class E2HReduction:
|
||||
|
||||
def prepare_graphs(self):
|
||||
last_file_header = AmorHeader(self.file_list[-1])
|
||||
self.overwrite.perform_action(last_file_header)
|
||||
tthh = last_file_header.geometry.nu - last_file_header.geometry.mu
|
||||
|
||||
if not self.config.reduction.is_default('thetaRangeR'):
|
||||
|
||||
@@ -117,7 +117,7 @@ class ReflectivityReduction:
|
||||
plt.show()
|
||||
|
||||
def read_file_block(self, i, short_notation):
|
||||
logging.warning('reading input:')
|
||||
logging.warning('input:')
|
||||
file_list = self.path_resolver.resolve(short_notation)
|
||||
|
||||
self.header.measurement_data_files = []
|
||||
@@ -159,7 +159,7 @@ class ReflectivityReduction:
|
||||
|
||||
def analyze_unsliced(self, i):
|
||||
self.monitor = self.dataset.data.pulses.monitor.sum()
|
||||
logging.warning(f' monitor = {self.monitor:8.2f} {MONITOR_UNITS[self.config.experiment.monitorType]}')
|
||||
logging.info(f' monitor = {self.monitor:8.2f} {MONITOR_UNITS[self.config.experiment.monitorType]}')
|
||||
|
||||
proj:LZProjection = self.project_on_lz()
|
||||
try:
|
||||
|
||||
@@ -37,6 +37,7 @@ hist_tofz = device('nicos_sinq.devices.just_bin_it.JustBinItImage',
|
||||
```
|
||||
|
||||
These images have then to be set in the detector configuration as _images_ items:
|
||||
|
||||
```
|
||||
images=['hist_yz', 'hist_tofz'],
|
||||
```
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user