@@ -321,12 +321,19 @@ def additional_readable_signals(self, dae: Dae) -> list[Device]:
321321class PeriodSpecIntegralsReducer (Reducer , StandardReadable ):
322322 """A DAE Reducer which simultaneously exposes integrals of many spectra in the current period.
323323
324- Two types of integrals are available: detectors and monitors. Other than defaults, their
325- behaviour is identical. No normalization is performed in this reducer - exactly how the
326- detector and monitor integrals are used is defined downstream.
324+ Two types of integrals are available: detectors and monitors.
327325
328- By itself, the data from this reducer is not suitable for use in a scan - but it provides
329- raw data which may be useful for further processing as part of callbacks (e.g. LiveDispatchers).
326+ The exposed signals are:
327+
328+ - det_integrals (1-dimensional array)
329+ - mon_integrals (1-dimensional array)
330+
331+ For convenience, three additional properties are also exposed:
332+
333+ - det_sum (scalar) - the sum of detector intensities across every detector.
334+ - mon_sum (scalar) - the sum of monitor intensities across every monitor.
335+ - intensity (scalar) - det_sum / mon_sum
336+ - intensity_stddev (scalar) - det_sum / mon_sum
330337 """
331338
332339 def __init__ (
@@ -354,6 +361,10 @@ def __init__(
354361 self .mon_integrals , self ._mon_integrals_setter = soft_signal_r_and_setter (
355362 Array1D [np .int32 ], np .ndarray ([], dtype = np .int32 )
356363 )
364+ self .det_sum , self ._det_sum_setter = soft_signal_r_and_setter (int , 0 )
365+ self .mon_sum , self ._mon_sum_setter = soft_signal_r_and_setter (int , 0 )
366+ self .intensity , self ._intensity_setter = soft_signal_r_and_setter (float , 0.0 )
367+ self .intensity_stddev , self ._intensity_stddev_setter = soft_signal_r_and_setter (float , 0.0 )
357368
358369 super ().__init__ (name = "" )
359370
@@ -393,13 +404,28 @@ async def reduce_data(self, dae: Dae) -> None:
393404 self ._det_integrals_setter (det_integrals )
394405 self ._mon_integrals_setter (mon_integrals )
395406
407+ scalar_det_sum = det_integrals .sum ()
408+ scalar_mon_sum = mon_integrals .sum ()
409+ self ._det_sum_setter (scalar_det_sum )
410+ self ._mon_sum_setter (scalar_mon_sum )
411+
412+ normalized = sc .scalar (
413+ scalar_det_sum , variance = scalar_det_sum + VARIANCE_ADDITION , dtype = "float64"
414+ ) / sc .scalar (scalar_mon_sum , variance = scalar_mon_sum + VARIANCE_ADDITION , dtype = "float64" )
415+ self ._intensity_setter (normalized .value )
416+ self ._intensity_stddev_setter (normalized .variance ** 0.5 )
417+
396418 logger .info ("reduction complete" )
397419
398420 def additional_readable_signals (self , dae : Dae ) -> list [Device ]:
399421 """Publish interesting signals derived or used by this reducer."""
400422 return [
401423 self .mon_integrals ,
402424 self .det_integrals ,
425+ self .det_sum ,
426+ self .mon_sum ,
427+ self .intensity ,
428+ self .intensity_stddev ,
403429 ]
404430
405431
0 commit comments