RatInABox-Lab / RatInABox

A python package for modelling locomotion in complex environments and spatially/velocity selective cell activity.
MIT License
175 stars 31 forks source link

1D rate map plot is blank due to NaNs #44

Closed colleenjg closed 1 year ago

colleenjg commented 1 year ago

I was running Neurons.plot_rate_map(method="history") with a 1D environment, and getting blank rate maps. I realized that in Neurons.py, line 463, if there are any NaNs in the binned data obtained from utils.bin_data_for_histogramming(), at line 471, they are propagated when you run utils.interpolate_and_smooth(). (In my case, they were propagated through the whole map). However, NaN values are expected for any position in the map that was never visited by the Agent.

Possible fixes: Do you prefer to (1) remove the positions with NaN rate map estimates from x and rate_map before running the interpolation, or (2) interpret NaNs as 0s for the purpose of interpolation?

TomGeorge1234 commented 1 year ago

good spot. I think I've already encountered and fixed this in 2D where I opted that unvisited positions essentially return 0 firing rate.

As you'll have figured: the way this is done is that position histograms, weighted by firing rate, are calculated are then normalised against how many times a position was visited. In 2D is a position was never visited bincount == 0 on utils.py line 456 then its bumped up to 1. This ultimately gives zero firing rate for unvisited locations but avoids the NaN (0/0 = NaN👎🏼, 0/1 = 0👍🏼 ). I clearly forgot to do the same for 1D too. I just pushed a one line fix. Should be fixed now

Imo this is the best way to do it - trying to be more clever about interpolating unvisited positions feels shady and not the way to go. One thing we could tweak is the interpolate_and_smooth() smoothing kernel width (sigma=0.03 in 1D, not applied in 2D but equivalent smoothing come for free with matplotlib.imshow()). Potentially could be increased but I dunno...kinda seems to work.

colleenjg commented 1 year ago

It worked, thanks! I think it's fine the way you've implemented it