Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tofu/data/_comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ def func(pts, vect=None, t=None, ntall=ntall,
shapeval = list(pts.shape)
shapeval[0] = ntall if t is None else t.size
val = np.full(tuple(shapeval), fill_value)

if t is None:
for ii in range(0,ntall):
val[ii,...] = mplTriLinInterp(mpltri,
Expand Down
12 changes: 8 additions & 4 deletions tofu/data/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3677,11 +3677,15 @@ def _get_indtu(t=None, tall=None, tbinall=None,
# Get indt (t with respect to tbinall)
indt, indtu = None, None
if t is not None:
indt = np.digitize(t, tbinall)
indtu = np.unique(indt)
if len(t) == len(tall) and np.allclose(t, tall):
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handle trivial case first, particularly suited for cases with t.size = 1

indt = np.arange(0, tall.size)
indtu = indt
else:
indt = np.digitize(t, tbinall)
indtu = np.unique(indt)
# Update
tall = tall[indtu]

# Update
tall = tall[indtu]
if idref1d is not None:
assert indtr1 is not None
indtr1 = indtr1[indtu]
Expand Down
59 changes: 21 additions & 38 deletions tofu/geom/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6025,7 +6025,7 @@ def calc_signal(
reflections=True,
coefs=None,
ind=None,
out=object,
returnas=object,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much more explicit variable name, especially since we tend to use 'out' to store temporary output inside functions.
It as the case in the other method by the way (calc_signal_from_Plasma2D()), out was redefined at line 6254

plot=True,
dataname=None,
fs=None,
Expand Down Expand Up @@ -6086,7 +6086,7 @@ def calc_signal(
# Format input

indok, Ds, us, DL, E = self._calc_signal_preformat(
ind=ind, DL=DL, out=out, Brightness=Brightness
ind=ind, DL=DL, out=returnas, Brightness=Brightness
)

if Ds is None:
Expand Down Expand Up @@ -6180,19 +6180,9 @@ def calc_signal(
# and interferometer)
val = func(pts, t=t, vect=vect)
# Integrate
if val.ndim == 2:
sig = np.full((val.shape[0], self.nRays), np.nan)
else:
sig = np.full((1, self.nRays), np.nan)
indpts = np.r_[0, indpts, pts.shape[1]]
for ii in range(0, self.nRays):
sig[:, ii] = (
np.nansum(
val[:, indpts[ii]:indpts[ii + 1]],
axis=-1
)
* reseff[ii]
)
sig = np.add.reduceat(val, np.r_[0, indpts],
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More concise and numerically faster, only advantages :-)
Usable in _GG.LOS_calc_signal(method='sum', minimize='calls') ?
Usable elsewhere ?

Compatible with parallelization ?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nope, only functions that don't require gil can be parallelized, calling numpy functions requires the gil, so it is not possible. This is why it wasn't parallelized with newcalc=True

axis=-1)*reseff[None, :]

# Format output
return self._calc_signal_postformat(
sig,
Expand All @@ -6202,7 +6192,7 @@ def calc_signal(
E=E,
units=units,
plot=plot,
out=out,
out=returnas,
fs=fs,
dmargin=dmargin,
wintit=wintit,
Expand Down Expand Up @@ -6236,7 +6226,7 @@ def calc_signal_from_Plasma2D(
reflections=True,
coefs=None,
ind=None,
out=object,
returnas=object,
plot=True,
dataname=None,
fs=None,
Expand All @@ -6250,7 +6240,7 @@ def calc_signal_from_Plasma2D(

# Format input
indok, Ds, us, DL, E = self._calc_signal_preformat(
ind=ind, out=out, t=t, Brightness=Brightness
ind=ind, out=returnas, t=t, Brightness=Brightness
)

if Ds is None:
Expand All @@ -6262,12 +6252,12 @@ def calc_signal_from_Plasma2D(
# Get time vector
if t is None:
out = plasma2d._checkformat_qr12RPZ(
quant=quant,
ref1d=ref1d,
ref2d=ref2d,
q2dR=q2dR,
q2dPhi=q2dPhi,
q2dZ=q2dZ,
quant=quant,
ref1d=ref1d,
ref2d=ref2d,
q2dR=q2dR,
q2dPhi=q2dPhi,
q2dZ=q2dZ,
)
t = plasma2d._get_tcom(*out[:4])[0]
else:
Expand Down Expand Up @@ -6368,6 +6358,8 @@ def funcbis(*args, **kwdargs):
indpts[0], np.diff(indpts), pts.shape[1] - indpts[-1]
]
vect = np.repeat(self.u, nbrep, axis=1)
if fill_value is None:
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid nans, they are not handled by np.add.reduceat() => we set fill_value to 0 instead in this case (if not forced by the user)

fill_value = 0.

# Get quantity values at ptsRZ
# This is the slowest step (~3.8 s with res=0.02
Expand All @@ -6388,19 +6380,10 @@ def funcbis(*args, **kwdargs):
fill_value=fill_value,
)

# Integrate
if val.ndim == 2:
sig = np.full((val.shape[0], self.nRays), np.nan)
else:
sig = np.full((1, self.nRays), np.nan)

indpts = np.r_[0, indpts, pts.shape[1]]
for ii in range(0, self.nRays):
sig[:, ii] = (
np.nansum(val[:, indpts[ii]:indpts[ii + 1]],
axis=-1)
* reseff[ii]
)
# Integrate using ufunc reduceat for speed
# (cf. https://stackoverflow.com/questions/59079141)
sig = np.add.reduceat(val, np.r_[0, indpts],
axis=-1)*reseff[None, :]

# Format output
# this is the secod slowest step (~0.75 s)
Expand All @@ -6412,7 +6395,7 @@ def funcbis(*args, **kwdargs):
E=E,
units=units,
plot=plot,
out=out,
out=returnas,
fs=fs,
dmargin=dmargin,
wintit=wintit,
Expand Down
2 changes: 1 addition & 1 deletion tofu/tests/tests01_geom/tests03_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,7 @@ def ffT(Pts, t=None, vect=None):
resMode=rm,
method=dm, minimize=mmz,
ind=ind,
plot=False, out=np.ndarray,
plot=False, returnas=np.ndarray,
fs=(12, 6), connect=connect)
sig, units = out
assert not np.all(np.isnan(sig)), str(ii)
Expand Down
2 changes: 1 addition & 1 deletion tofu/tests/tests02_data/tests03_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ def setup_class(cls, nch=30, nt=50, SavePath='./', verb=False):
lData = [None for ii in range(0,len(lc))]
for ii in range(0,len(lc)):
sig = lc[ii].calc_signal(emiss, t=t, res=0.01, method=lm[ii],
plot=False, out=np.ndarray)[0]
plot=False, returnas=np.ndarray)[0]
sig = sig[:,:,None]*flamb[None,None,:]
cla = eval('tfd.DataCam%sDSpectral'%('2' if lc[ii]._is2D() else '1'))
data = cla(data=sig, Name='All', Diag='Test',
Expand Down