The DoOR.functions
package provides tools for the analysis of the data
provided by the DoOR.data
package.
identify_sensillum()
](private_odorant()
map_receptor()
](First we need to load packages and data:
#load data library(DoOR.functions) library(DoOR.data) load_door_data(nointeraction = TRUE)
identify_sensillum()
{#identify_sensillum}
Imagine we perform an electrophysiological recording from a Drosophila
sensillum (single sensillum recording, SSR) and we are not sure what sensillum
we are recording from. In order to identify the sensillum we used several
diagnostic odorants (maybe selected using
private_odorant()
) and got responses from the different
sensory neurons the sensillum houses. We can now pass our recorded data to
identify_sensillum()
.
Let's make up some simple fake data. We pretend to have recorded with three
odorants (2,3-butanedione, ethanoic acid and carbon dioxide) and we could
separate the responses of two units. Unit1 responded strongly to 2,3-butanedione
only, unit2 only responded to carbon dioxide. We create a data.frame that
contains a column called odorants
with the InChIKeys of our test odorants, and
one column for each unit (name the colnames as you like, e.g. unit1-n or Aneuro
if you are sure about the neuron).
recording <- data.frame( odorants = c(trans_id(c("BEDN", "ETAS"), "Code"), trans_id("carbon dioxide", "Name")), unit1 = c(.9,.1,.1), unit2 = c(0, .1, 1) )
Next we feed the recording to the function:
identify_sensillum(recording, base_size = 8)
Note that the function tells us that it found hits for all units in ab1 and ab5,
meaning that e.g. within the four neurons housed in the ab1 sensillum both of
our units had good matches. You can set this correlation threshold with
min.cor
. If we increase the threshold to 0.99 only ab1 is returned as a double
match:
identify_sensillum(recording, min.cor = .99)
We can define the number of best hits that we want to get returned (the default is 10):
identify_sensillum(recording, nshow = 5, base_size = 8)
And if we know e.g. that we are recording from a basiconic sensillum we can restrict the search to one or a few sensilla types:
identify_sensillum(recording, sub = "ab", nshow = 5, base_size = 8) identify_sensillum(recording, sub = c("ac","at"), nshow = 5, base_size = 8)
Instead of correlations we can also use the Euclidean distance as a (dis)similarity measure:
identify_sensillum(recording, method = "dist", sub = "ab", nshow = 5, base_size = 8)
We can also return the correlation/distance data instead of the plot when
setting plot =FALSE
:
sensillumX <- identify_sensillum(recording, method = "dist", sub = "ab", plot = FALSE) head(sensillumX)
So apparently our fake recording came from the ab1 sensillum, which was admittedly quite obvious as we had a strong carbon dioxide response and ab1 houses the carbon dioxide receptor :)
private_odorant()
{#private_odorant}There may be several cases where we might be interested in so called
private odorants, odorants that specifically activate a given receptor or
sensory neuron. Maybe we are looking for diagnostic odorants for sensillum
identification or we want to activate a specific neuronal pathway,
private_odorant()
returns candidate odorants for that task.
Let's say we want to specifically activate Or22a neurons:
private_odorant("Or22a")
We might want to return the odorant names instead of InChiKeys:
private_odorant("Or22a", tag = "Name")
So according to the function sec-amyl acetate would be a good candidate. It activates Or22a at 0.4 (DoOR response, max is 1) while the maximum activation in all other tested responding units (receptors, neurons, glomeruli) is 0.016, a difference of 0.40. Sounds good, but it was tested only in 4 other responding units, so I would rather go for ethyl hexanoate with about the same difference but being tested in 29 other responding units.
We can also restrict the search to the sensillum the responding units of interest is related to:
private_odorant("Or22a", tag = "Name", sensillum = T)
Ethyl 2-methylbutanoate sounds like a good hit, it has the same difference to the other units as ethyl hexanoate but hardly elicits a response at all from the other neuron. The n of 1 is fine as there are only 2 neurons housed in the ab3 sensillum.
map_receptor()
{#map_receptor}
Similar to identify_sensillum()
, map_receptor()
correlates a response vector
to all responding units of the existing DoOR consensus data. Let's grab a data
set from Or22a and see where it ends up:
data <- data.frame(odorants = Or22a$InChIKey, responses = Or22a$Hallem.2006.EN) data <- na.omit(data) head(data) map_receptor(data = data, nshow = 5)
This example was a bit circular as the tested data contributed to the consensus data...
back_project()
{#back_project}
The DoOR consensus data is normalized to values between 0 and 1. If we want to
compare the DoOR data to one of our own recordings, it would be great to have
the DoOR data in the same unit as our owne data (e.g. spikerate). This is what
we can do with back_project()
, we can rescale the DoOR data to fit a given
response template.
As an example, let's take the data Hallem et al. recorded from Or22a via
calcium imaging and rescale the DoOR responses accordingly. The template has to
have 2 columns named odorants
and responses
:
template <- data.frame(odorants = Or22a$InChIKey, responses = Or22a$Hallem.2006.EN) bp <- back_project(template, responding.unit = "Or22a") plot(bp$back_projected$original.data, bp$back_projected$back_projected.data, xlab = "DoOR consensus response", ylab = "back_projected data [spikes, Hallem.2006.EN]" ) head(bp$back_projected)
All the yellow lines in the first plot represent odorant responses that were not available in the original data set but were projected onto the fitted function and rescaled to the units in "Hallem.2006.EN". The second plot shows the relationship between the rescaled data and the original consensus responses.
sparse()
{#sparse}The width of a tuning curve, i.e. for example to how many odorants a receptor
shows strong responses, can be quantified using different sparseness measures.
We implemented kurtosis[^1] and sparseness[^2] in sparse()
. A high kurtosis or
sparseness value indicates a narrow tuning curve (see also dplot_tuningCurve()
in the DoOR visualization vignette).
While kurtosis is able to deal with negative values, sparseness can't and thus
all values need to be be transformed to absolute values first. Sparseness scales
between 0 and 1, kurtosis between -∞ and ∞, a kurtisis of 0 corresponds to the
Gaussian distribution.
rm.SFRreset <- reset_sfr(door_response_matrix, "SFR") sparse(x = rm.SFRreset[,"Or69a"], method = "ltk") sparse(x = rm.SFRreset[,"Or69a"], method = "lts") sparse(x = rm.SFRreset[,"Gr21a.Gr63a"], method = "ltk") sparse(x = abs(rm.SFRreset[,"Gr21a.Gr63a"]), method = "lts")
[^1]: Willmore, B., Tolhurst, D.J., 2001. Characterizing the sparseness of neural codes. Network 12, 255–270. dx.doi.org/10.1080/net.12.3.255.270 [^2]: Bhandawat, V., Olsen, S.R., Gouwens, N.W., Schlief, M.L., Wilson, R.I., 2007. Sensory processing in the Drosophila antennal lobe increases reliability and separability of ensemble odor representations. Nature neuroscience 10, 1474–82. dx.doi.org/10.1038/nn1976
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.