touchsim tutorial

This notebook demonstrates some basic functionality of the touchsim package. For more on the in-built plotting options, see touchsim_plotting.ipynb. For a quick guide on overloaded functions see touchsim_shortcuts.ipynb.

In [ ]:
import touchsim as ts # import touchsim package
from touchsim.plotting import plot # import in-built plotting function
import numpy as np
import holoviews as hv # import holoviews package for plots and set some parameters
hv.notebook_extension()
%output holomap='scrubber'

import warnings
warnings.simplefilter("ignore")

Hand regions and the coordinate system

touchsim includes a model of the hand surface. Its coordinate system is centered on the distal pad of the index finger. The first axis extends along the index finger towards the base and palm, while the second axis extends orthogonally towards the middle finger. Other spatial layouts can be used via the Surface class.

In [ ]:
%%output size=150
plot(coord=10)

Generating individual afferents and populations

Single afferents belong to the Afferent class.

In [ ]:
a1 = ts.Afferent('SA1',surface=ts.hand_surface) # generate SA1 afferent located at the origin

plot(region='D2') * plot(a1,size=10)

Afferent objects can be placed anywhere on the skin surface.

In [ ]:
# generate PC afferent on distal pad of middle finger
a2 = ts.Afferent('PC',surface=ts.hand_surface,location=ts.hand_surface.centers[ts.hand_surface.tag2idx('D3d')])

plot() * plot(a2,size=10)

Multiple Afferent objects combine into an AfferentPopulation object.

In [ ]:
a = a1 + a2
print(a)

touchsim includes several affpop_* functions that generate commonly used AfferentPopulation objects. For example affpop_grid places afferents on a grid. affpop_hand places afferents on the hand model, in realistic densities. It can be limited to a specific hand region, afferent class, and the overall density can be adjusted.

In [ ]:
a_d2 = ts.affpop_hand(region='D2') # limit to digit 2
a_RA = ts.affpop_hand(affclass='RA') # limit to RA afferents
a = ts.affpop_hand(density_multiplier=0.2) # decrease density

plot() * plot(a_d2) + plot() * plot(a_RA) + plot() * plot(a)

Generating touch stimuli

Tactile stimuli are represented in touchsim using Stimulus objects. These consist of individual pins. Each pin is assigned a location on the skin surface and its movements orthogonal to the skin surface is described as a time-varying trace function.

In [ ]:
loc = np.zeros((1,2))
trace = 0.1 * np.sin(np.linspace(0.,2.*np.pi*10,5000))
s = ts.Stimulus(location = loc, trace = trace, fs=5000)

plot(s)

Generating simple stimuli

A number of commonly used stimuli are implemented as stim_* functions. These include

  • stim_ramp for ramp-hand-hold indentations
  • stim_sine for sinusoidal vibrations
  • stim_noise for bandpass white noise stimuli
  • stim_impulse for brief "taps" of the skin
In [ ]:
s_ramp = ts.stim_ramp(amp=0.1)
s_sine = ts.stim_sine(amp=0.05,freq=50)
s_noise = ts.stim_noise()
s_impulse = ts.stim_impulse(pad_len = 0.4)

plot(s_ramp) + plot(s_sine) + plot(s_noise) + plot(s_impulse)

Generating complex stimuli

Complex stimuli can be generated by combining an object shape, that is a specific spatial pin layout, with a movement trace that is applied to all pins simultaneously. The example below creates a large rounded probe, which is then indented into the skin using a ramp-and-hold pattern. The stim_indent_shape method is used to combine the spatial pin layout, here created using a shape_* function, with a movement trace, created using a stim_* function.

In [ ]:
s = ts.stim_indent_shape(ts.shape_circle(hdiff=0.5,pins_per_mm=2,radius=3),ts.stim_ramp(len=0.1,pad_len=0.01))

plot(region='D2d') * plot(s,spatial=True,bin=10)

Calculating responses

The response method of Afferent and AfferentPopulation objects calculates the spiking response to any Stimulus object.

In [ ]:
r = a.response(s) # calculate response of a to s.

# Plot response as raster plot and spatially on finger
plot(r) + plot() * plot(r,spatial=True,scaling_factor=0.1)

Responses can be plotted as animations.

In [ ]:
plot() * plot(r,spatial=True,bin=5)

Getting help

Check the docstrings of functions and classes for additional help.

In [ ]:
?ts.stim_ramp

Objects can also print information about themselves.

In [ ]:
print(r)