Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MRG, ENH: Fix memory on CircleCI #8379

Merged
merged 26 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5a9c418
ENH: Add memory to circle [skip travis] [skip github]
larsoner Oct 16, 2020
ca85fdf
ENH: Better memory
larsoner Oct 16, 2020
e7c6b9f
FIX: No second param [circle full]
larsoner Oct 16, 2020
3230043
FIX: Download [circle full]
larsoner Oct 16, 2020
81836fb
BUG: Fix for latest mpl [circle full]
larsoner Oct 20, 2020
5738bb4
FIX: Order [circle full]
larsoner Oct 20, 2020
2624270
FIX: is_first_col dep
larsoner Oct 20, 2020
6dcc394
FIX: Old mpl
larsoner Oct 20, 2020
2c2302f
FIX: Fix problematic bound methods [circle full]
larsoner Oct 20, 2020
3d5373d
ENH: Tighter doc build [circle full]
larsoner Oct 20, 2020
7251a62
FIX: Mem usage [circle full]
larsoner Oct 20, 2020
42af768
FIX: Split multi 3D [circle full]
larsoner Oct 20, 2020
e1bb4e9
FIX: inf/nan [circle full]
larsoner Oct 20, 2020
c9a3078
FIX: More [circle full]
larsoner Oct 21, 2020
15ca9c8
ENH: Better sensors [circle full]
larsoner Oct 21, 2020
510da25
STY: Flake [circle full]
larsoner Oct 21, 2020
13ce561
TST: Add test [circle full]
larsoner Oct 21, 2020
8d31c08
Fix test_brain_init
GuillaumeFavelier Oct 22, 2020
b400fd3
Improve test_brain_traces
GuillaumeFavelier Oct 22, 2020
d28a4b3
Fix segfault
GuillaumeFavelier Oct 22, 2020
d1861b5
Fix test_brain_traces
GuillaumeFavelier Oct 22, 2020
132f47c
Finish with test_brain.py
GuillaumeFavelier Oct 22, 2020
2ce07ac
TST: Circle [circle full]
larsoner Oct 22, 2020
73be960
Remove some brain_gcs [circle full]
GuillaumeFavelier Oct 22, 2020
3ab92c9
ENH: Lower memory [circle full]
larsoner Oct 22, 2020
278608f
BUG: Fixes [circle full]
larsoner Oct 22, 2020
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
2 changes: 1 addition & 1 deletion examples/inverse/plot_resolution_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
function='psf', metric='peak_err')
sd_dspm_psf = resolution_metrics(rm_dspm, inverse_operator['src'],
function='psf', metric='sd_ext')
del rm_dspm
del rm_dspm, forward

###############################################################################
# Visualize results
Expand Down
30 changes: 15 additions & 15 deletions mne/minimum_norm/spatial_resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,30 +146,32 @@ def _localisation_error(resmat, src, function, metric):
resmat = _rectify_resolution_matrix(resmat)
locations = _get_src_locations(src) # locs used in forw. and inv. operator
locations = 100. * locations # convert to cm (more common)
resmat = np.absolute(resmat) # only use absolute values
# we want to use absolute values, but doing abs() mases a copy and this
# can be quite expensive in memory. So let's just use abs() in place below.
Comment on lines -149 to +150
Copy link
Member Author

Choose a reason for hiding this comment

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

FYI @olafhauk these matrices can be quite large (~8000x8000), so instead of doing this operation here, I've moved it to be done column-wise. It shouldn't be an appreciable performance difference but it should lower memory usage by ~800 MB in the plot_resolution_metrics.py example.


# The code below will operate on columns, so transpose if you want CTFs
if function == 'ctf':
resmat = resmat.T

# Euclidean distance between true location and maximum
if metric == 'peak_err':
resmax = resmat.argmax(axis=0) # find indices of maxima along columns
resmax = [abs(col).argmax() for col in resmat.T] # max inds along cols
maxloc = locations[resmax, :] # locations of maxima
diffloc = locations - maxloc # diff btw true locs and maxima locs
locerr = np.sqrt(np.sum(diffloc ** 2, 1)) # Euclidean distance
locerr = np.linalg.norm(diffloc, axis=1) # Euclidean distance

# centre of gravity
elif metric == 'cog_err':
locerr = np.empty(locations.shape[0]) # initialise result array
for ii, rr in enumerate(locations):
resvec = resmat[:, ii].T # corresponding column of resmat
resvec = abs(resmat[:, ii].T) # corresponding column of resmat
cog = resvec.dot(locations) / np.sum(resvec) # centre of gravity
locerr[ii] = np.sqrt(np.sum((rr - cog) ** 2)) # Euclidean distance

return locerr


#@profile
def _spatial_extent(resmat, src, function, metric, threshold=0.5):
"""Compute spatial width metrics for resolution matrix.

Expand Down Expand Up @@ -202,31 +204,29 @@ def _spatial_extent(resmat, src, function, metric, threshold=0.5):
"""
locations = _get_src_locations(src) # locs used in forw. and inv. operator
locations = 100. * locations # convert to cm (more common)
resmat = np.absolute(resmat) # only use absolute values

# The code below will operate on columns, so transpose if you want CTFs
if function == 'ctf':
resmat = resmat.T

resmax = resmat.argmax(axis=0) # find indices of maxima along rows
width = np.empty(len(resmax)) # initialise output array
width = np.empty(resmat.shape[1]) # initialise output array

# spatial deviation as in Molins et al.
if metric == 'sd_ext':
for ii in range(locations.shape[0]):

diffloc = locations - locations[ii, :] # locs w/r/t true source
locerr = np.sum(diffloc**2, 1) # squared Eucl dists to true source
resvec = resmat[:, ii]**2 # pick current row
resvec = abs(resmat[:, ii]) ** 2 # pick current row
# spatial deviation (Molins et al, NI 2008, eq. 12)
width[ii] = np.sqrt(np.sum(np.multiply(locerr, resvec)) /
np.sum(resvec))

# maximum radius to 50% of max amplitude
elif metric == 'maxrad_ext':
maxamp = resmat.max(axis=0) # peak ampl. per location across columns
for ii, amps in enumerate(maxamp): # for all locations
resvec = resmat[:, ii] # pick current column
for ii, resvec in enumerate(resmat.T): # iterate over columns
resvec = abs(resvec) # operate on absolute values
amps = resvec.max()
# indices of elements with values larger than fraction threshold
# of peak amplitude
thresh_idx = np.where(resvec > threshold * amps)
Expand Down Expand Up @@ -269,17 +269,17 @@ def _relative_amplitude(resmat, src, function, metric):
if function == 'ctf':
resmat = resmat.T

resmat = np.absolute(resmat) # only use absolute values

# Ratio between amplitude at peak and global peak maximum
if metric == 'peak_amp':
maxamps = resmat.max(axis=0) # maximum amplitudes per column
# maximum amplitudes per column
maxamps = np.array([abs(col).max() for col in resmat.T])
maxmaxamps = maxamps.max() # global absolute maximum
relamp = maxamps / maxmaxamps

# ratio between sums of absolute amplitudes
elif metric == 'sum_amp':
sumamps = np.sum(resmat, axis=0) # sum of amplitudes per column
# sum of amplitudes per column
sumamps = np.array([abs(col).sum() for col in resmat.T])
sumampsmax = sumamps.max() # maximum of summed amplitudes
relamp = sumamps / sumampsmax

Expand Down