Skip to content

Commit 344a033

Browse files
committed
compute_n_to_1 function func takes now an object list as argument
1 parent 55d28d4 commit 344a033

9 files changed

Lines changed: 276 additions & 160 deletions

File tree

cdl/computation/base.py

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@
1717
import guidata.dataset as gds
1818
import numpy as np
1919

20+
from cdl.algorithms.datatypes import is_complex_dtype
2021
from cdl.config import Conf, _
21-
from cdl.obj import ResultProperties, create_signal
22+
from cdl.obj import ImageObj, ResultProperties, SignalObj, create_signal
2223

2324
if TYPE_CHECKING:
2425
from typing import Callable
2526

26-
from cdl.obj import ImageObj, SignalObj
27-
2827

2928
class ArithmeticParam(gds.DataSet):
3029
"""Arithmetic parameters"""
@@ -205,6 +204,59 @@ def dst_1_to_1(
205204
return dst
206205

207206

207+
def dst_n_to_1(
208+
src_list: list[SignalObj | ImageObj],
209+
name: str,
210+
suffix: str | None = None,
211+
) -> SignalObj | ImageObj:
212+
"""Create a result object, as returned by the callback function of the
213+
:func:`cdl.core.gui.processor.base.BaseProcessor.compute_n_to_1` method
214+
215+
.. note::
216+
217+
Data of the result object is copied from the first source object
218+
(`src_list[0]`). This initial data is usually replaced by the processing
219+
function, but it may also be used to initialize the result object as part
220+
of the processing function.
221+
222+
Args:
223+
src_list: list of input signal or image objects
224+
name: name of the processing function
225+
suffix: suffix to add to the title
226+
227+
Returns:
228+
Result signal or image object
229+
"""
230+
if not isinstance(src_list, list) or len(src_list) <= 1:
231+
raise ValueError("src_list must be a list of at least 2 objects")
232+
all_sigs = all([isinstance(obj, SignalObj) for obj in src_list])
233+
all_imgs = all([isinstance(obj, ImageObj) for obj in src_list])
234+
if not (all_sigs or all_imgs):
235+
raise ValueError("src_list must be a list of SignalObj or ImageObj objects")
236+
title = f"{name}({', '.join([obj.short_id for obj in src_list])})"
237+
if suffix: # suffix may be None or an empty string
238+
title += "|" + suffix
239+
if any([is_complex_dtype(obj.data.dtype) for obj in src_list]):
240+
dst_dtype = complex
241+
else:
242+
dst_dtype = float
243+
dst = src_list[0].copy(title=title, dtype=dst_dtype)
244+
dst.roi = None
245+
if not Conf.proc.keep_results.get():
246+
dst.delete_results() # Remove any previous results
247+
for src_obj in src_list:
248+
if Conf.proc.keep_results.get():
249+
dst.update_resultshapes_from(src_obj)
250+
if src_obj.roi is not None:
251+
if dst.roi is None:
252+
dst.roi = src_obj.roi.copy()
253+
else:
254+
roi = dst.roi
255+
roi.add_roi(src_obj.roi)
256+
dst.roi = roi
257+
return dst
258+
259+
208260
def dst_n1n(
209261
src1: SignalObj | ImageObj,
210262
src2: SignalObj | ImageObj,

cdl/computation/image/__init__.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
calc_resultproperties,
4545
dst_1_to_1,
4646
dst_n1n,
47+
dst_n_to_1,
4748
new_signal_result,
4849
)
4950
from cdl.config import Conf, _
@@ -167,33 +168,52 @@ def dst_1_to_1_signal(src: ImageObj, name: str, suffix: str | None = None) -> Si
167168
# the modified object from the worker processes.
168169

169170

170-
def compute_addition(dst: ImageObj, src: ImageObj) -> ImageObj:
171-
"""Add **dst** and **src** images and return **dst** image modified in place
171+
def compute_addition(src_list: list[ImageObj]) -> ImageObj:
172+
"""Add images in the list and return the result image object
172173
173174
Args:
174-
dst: output image object
175-
src: input image object
175+
src_list: list of input image objects
176176
177177
Returns:
178178
Output image object (modified in place)
179179
"""
180-
dst.data = np.add(dst.data, src.data, dtype=float)
181-
restore_data_outside_roi(dst, src)
180+
dst = dst_n_to_1(src_list, "Σ") # `dst` data is initialized to `src_list[0]` data
181+
for src in src_list[1:]:
182+
dst.data = np.add(dst.data, src.data, dtype=float)
183+
restore_data_outside_roi(dst, src_list[0])
182184
return dst
183185

184186

185-
def compute_product(dst: ImageObj, src: ImageObj) -> ImageObj:
186-
"""Multiply **dst** and **src** images and return **dst** image modified in place
187+
def compute_average(src_list: list[ImageObj]) -> ImageObj:
188+
"""Compute the average of images in the list and return the result image object
187189
188190
Args:
189-
dst: output image object
190-
src: input image object
191+
src_list: list of input image objects
191192
192193
Returns:
193194
Output image object (modified in place)
194195
"""
195-
dst.data = np.multiply(dst.data, src.data, dtype=float)
196-
restore_data_outside_roi(dst, src)
196+
dst = dst_n_to_1(src_list, "µ") # `dst` data is initialized to `src_list[0]` data
197+
for src in src_list[1:]:
198+
dst.data = np.add(dst.data, src.data, dtype=float)
199+
dst.data /= len(src_list)
200+
restore_data_outside_roi(dst, src_list[0])
201+
return dst
202+
203+
204+
def compute_product(src_list: list[ImageObj]) -> ImageObj:
205+
"""Multiply images in the list and return the result image object
206+
207+
Args:
208+
src_list: list of input image objects
209+
210+
Returns:
211+
Output image object (modified in place)
212+
"""
213+
dst = dst_n_to_1(src_list, "Π") # `dst` data is initialized to `src_list[0]` data
214+
for src in src_list[1:]:
215+
dst.data = np.multiply(dst.data, src.data, dtype=float)
216+
restore_data_outside_roi(dst, src_list[0])
197217
return dst
198218

199219

cdl/computation/signal.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
calc_resultproperties,
4040
dst_1_to_1,
4141
dst_n1n,
42+
dst_n_to_1,
4243
new_signal_result,
4344
)
4445
from cdl.config import Conf, _
@@ -138,37 +139,58 @@ def __call__(self, src: SignalObj) -> SignalObj:
138139
# the modified object from the worker processes.
139140

140141

141-
def compute_addition(dst: SignalObj, src: SignalObj) -> SignalObj:
142-
"""Add **dst** and **src** signals and return **dst** signal modified in place
142+
def compute_addition(src_list: list[SignalObj]) -> SignalObj:
143+
"""Add **src** signals and return a new result signal object
143144
144145
Args:
145-
dst: destination signal
146-
src: source signal
146+
src_list: list of source signals
147147
148148
Returns:
149149
Modified **dst** signal (modified in place)
150150
"""
151-
dst.y += np.array(src.y, dtype=dst.y.dtype)
152-
if dst.dy is not None:
153-
dst.dy = np.sqrt(dst.dy**2 + src.dy**2)
154-
restore_data_outside_roi(dst, src)
151+
dst = dst_n_to_1(src_list, "Σ") # `dst` data is initialized to `src_list[0]` data
152+
for src in src_list[1:]:
153+
dst.y += np.array(src.y, dtype=dst.y.dtype)
154+
if dst.dy is not None:
155+
dst.dy = np.sqrt(dst.dy**2 + src.dy**2)
156+
restore_data_outside_roi(dst, src_list[0])
155157
return dst
156158

157159

158-
def compute_product(dst: SignalObj, src: SignalObj) -> SignalObj:
159-
"""Multiply **dst** and **src** signals and return **dst** signal modified in place
160+
def compute_average(src_list: list[SignalObj]) -> SignalObj:
161+
"""Average **src** signals and return a new result signal object
160162
161163
Args:
162-
dst: destination signal
163-
src: source signal
164+
src_list: list of source signals
164165
165166
Returns:
166167
Modified **dst** signal (modified in place)
167168
"""
168-
dst.y *= np.array(src.y, dtype=dst.y.dtype)
169-
if dst.dy is not None:
170-
dst.dy = dst.y * np.sqrt((dst.dy / dst.y) ** 2 + (src.dy / src.y) ** 2)
171-
restore_data_outside_roi(dst, src)
169+
dst = dst_n_to_1(src_list, "µ") # `dst` data is initialized to `src_list[0]` data
170+
for src in src_list[1:]:
171+
dst.y += np.array(src.y, dtype=dst.y.dtype)
172+
if dst.dy is not None:
173+
dst.dy = np.sqrt(dst.dy**2 + src.dy**2)
174+
dst.y /= len(src_list)
175+
restore_data_outside_roi(dst, src_list[0])
176+
return dst
177+
178+
179+
def compute_product(src_list: list[SignalObj]) -> SignalObj:
180+
"""Multiply **dst** by **src** signals and return a new result signal object
181+
182+
Args:
183+
src_list: list of source signals
184+
185+
Returns:
186+
Modified **dst** signal (modified in place)
187+
"""
188+
dst = dst_n_to_1(src_list, "Π") # `dst` data is initialized to `src_list[0]` data
189+
for src in src_list[1:]:
190+
dst.y *= np.array(src.y, dtype=dst.y.dtype)
191+
if dst.dy is not None:
192+
dst.dy = dst.y * np.sqrt((dst.dy / dst.y) ** 2 + (src.dy / src.y) ** 2)
193+
restore_data_outside_roi(dst, src_list[0])
172194
return dst
173195

174196

0 commit comments

Comments
 (0)