Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Feb 02 10:22
    Bisaloo opened #243
  • Jan 09 23:49
    thomased closed #242
  • Jan 09 23:40
    thomased commented #242
  • Jan 08 21:11
    dmurdoch opened #242
  • Nov 29 2022 07:59
    Bisaloo opened #241
  • Nov 26 2022 17:21
    Bisaloo opened #240
  • Nov 10 2022 02:26
    thomased commented #239
  • Nov 10 2022 02:26
    thomased closed #239
  • Nov 05 2022 13:50
    Bisaloo review_requested #239
  • Nov 05 2022 12:49
    Bisaloo synchronize #239
  • Nov 05 2022 12:22
    Bisaloo synchronize #239
  • Nov 04 2022 16:58
    Bisaloo synchronize #239
  • Nov 04 2022 16:16
    Bisaloo synchronize #239
  • Jun 21 2022 01:42
    thomased closed #238
  • Jun 21 2022 01:41
    thomased commented #238
  • Jun 20 2022 10:30
    Bisaloo opened #238
  • Jun 20 2022 10:30
    Bisaloo review_requested #238
  • Jun 20 2022 10:27
    Bisaloo closed #235
  • Jun 19 2022 15:32
    juandemedel commented #235
  • Jun 19 2022 14:44
    Bisaloo commented #235
Hugo Gruson
@Bisaloo
Hi @leonosper_melissa:matrix.org, vissyst is an internal object and it is not meant to be called outside of pavo inners. If you want to get/visualise data used by vismodel(), you can use the sensdata() function: http://pavo.colrverse.com/reference/sensdata.html :smiley:
Melissa León
@leonosper_melissa:matrix.org
[m]
Hi @Bisaloo thank you so much! That's all I need!
Melissa León
@leonosper_melissa:matrix.org
[m]
Hello! Can anyone give me a reference or tell me the way PAVO calculates the achromatic contrast. I am confused if PAVO's achromatic contrast is the same as the known "green contrast". Thanks!
Thomas White
@thomased

Hey @leonosper_melissa:matrix.org! Fair question — I probably need to tweak the docs a bit to be honest. coldist() and bootcoldist() report the kinds of contrasts being calculated though, which should help. It's a bit space-specific, since different models demand different kinds of contrast. The receptor-noise model does it's own noise-weighted thing, for example, while 'generic' colourspaces (di- tri- tetrachromatic) use Weber contrast as standard.

Since you mention "green" contrast I'm guessing you might be using the hexagon? It returns simple luminance contrast which, if you specify the long-wavelength receptor as the 'achromatic' receptor and use the bee phenotype, does indeed correspond to "green contrast" as per all the literature, like you say. So the dL values returned in the below example are 'green contrast':

### Hexagon example

# Load data
data(flowers)

# Calculate qcatch w/ long receptor for achromatic
vis.flowers <- vismodel(flowers,
  visual = "apis", qcatch = "Ei", relative = FALSE,
  vonkries = TRUE, achromatic = "l", bkg = "green"
)

# Into the hexagon
flowers.hex <- colspace(vis.flowers, space = "hexagon")

# Distances/contrasts.  Here 'simple' luminance contrast therefore = green receptor contrast
coldist(flowers.hex)
Melissa León
@leonosper_melissa:matrix.org
[m]
Hey @thomased! (I think that in the example you forgot to set "achromatic=T" in "coldist" (?)). Yes I'm asking about "green contrast" for the hexagon, but I thought "green contrast" was the excitation of the long-wave photoreceptor - 0.50, and dL doesn't match with that.
Thomas White
@thomased

Argh, apologies - you're right. I'm a bit hex-rusty, and I think I may have spotted a small nearby bug too. But anyway, it's actually simpler than all that. So if I'm now understanding right for Spaethe et al. (2001)'s green contrast (as in "...the degree to which a stimulus generates an excitation value different from 0.5 in the green receptor...") you can just eyeball the 'l' column in the output from the call to vismodel then - no coldist() or achromatic required. If you're green-adapted, like in that above example and many papers that use the hex, then yeah the 'l' receptor output column gives what you're after (or you can adapt to any background as you like of course). E.g.

# Load data
data(flowers)

# Calculate qcatch w/ long receptor for achromatic
vis.flowers <- vismodel(flowers,
                        visual = "apis", qcatch = "Ei", relative = FALSE,
                        vonkries = TRUE, bkg = "green"
)

head(vis.flowers)

gives

> head(vis.flowers)
                               s         m         l lum
Goodenia_heterophylla 0.56572097 0.8237141 0.7053057  NA
Goodenia_geniculata   0.35761236 0.8176153 0.8670134  NA
Goodenia_gracilis     0.01888788 0.1622766 0.7810589  NA
Xyris_operculata      0.21080752 0.7345122 0.6796464  NA
Eucalyptus_sp         0.55622758 0.8515289 0.8208038  NA
Faradaya_splendida    0.45855056 0.7828905 0.8565895  NA

Which is giving fairly strong green-contrast (beyond 0.4 - 0.6 range), as you'd generally expect of a flower.

As another example, if you use the green background as both the stimulus and adapting background, you'd expect no contrast (so 0.5):

vis.green <- vismodel(sensdata(bkg = 'green'),
                        visual = "apis", qcatch = "Ei", relative = FALSE,
                        vonkries = TRUE, bkg = "green"
)

head(vis.green)

which is what you get

> head(vis.green)
        s   m   l lum
green 0.5 0.5 0.5  NA
Melissa León
@leonosper_melissa:matrix.org
[m]
@thomased: Okay! I think I get it! So, is this also applicable for every pollinator (birds, flies and even custom ones)? Making sure that you choose the green receptor of your pollinator if you set vonkries=T and bkg="green"? (i.e. tetrachromatic birds, I would use the 3rd photoreceptor that matches green wave-lengths)?
Thomas White
@thomased
Yeah sure, you could swap any viewer into the visual argument for the same idea. So no problem in practical terms, but conceptually it'd need some careful interpretation w/r/t your question(s). The hyperbolic transform is fairly bee-specific as far as I know, not sure birds or flies care about 'green' contrast per se (? flies mostly R1-6 for achro stuff), or at least there's not nearly as much evidence for them as for bees (to my knowledge - could be corrected!), etc. etc. The usual stuff to think about.
Melissa León
@leonosper_melissa:matrix.org
[m]
@thomased Sorry if I'm being picky but in Spaethe 2001, also says that the maximum value for green contrast is 0.50. If the "l" column of "vismodel" equals this parameter, how is it possible that Goodenia_heterophylla (vis.flowers in your last example) return a 0.7 value??
Thomas White
@thomased

No not picky at all - I haven't thought about this in a while. Good questions. So here it's a matter of terminology jumping around a bit. Spaethe et al. does say "Because excitation can range from 0 to 1, the maximum green contrast is 0.5.", which is right. Your quantum catches range from 0 - 1, and if "no contrast" is 0.5, then the maximum contrast would be abs(1 - 0.5) or abs(0 - 0.5) = 0.5, right? So the thing to keep in mind there is green contrast as the difference from 0.5, not the absolute green-receptor stimulation per se (range 0 - 1). So for those examples of mine above, Goodenia_heterophylla offers green contrast of ~0.305 (0.705 - 0.5), while the green background offers 0 (0.5 - 0.5). Does that make sense?

To add to the confusion it looks to me (at a quick glance) that people seem to quietly slip between the two formulations of green contrast as both the absolute receptor stimulation or the difference from 0.5. They're equivalent of course, but you'll just need to keep an eye out when interpreting specific numerical results & keep on top of which they're using.

Thomas White
@thomased

As another example from from Bukovac et al. 2017a (Why background colour matters....Dyer's group) - "...In particular, we use the definition given in Bukovac et al. (2016), and deem low green contrast to be where E(G) ∈ [0.4, 0.6]. Adapted to the ALG background, all three stimuli have high green contrast values E(G) ≥ 0.7....". So they're reporting absolute values there.

But then in Bukovac et al. 2017b (Assessing the ecological significance...) they use the other form in Table 1 - "Receptor contrasts given are excitation difference from 0.5..."

Melissa León
@leonosper_melissa:matrix.org
[m]
Hello! I'm back with more questions, this time about Troje categorical model. I'm looking for the formulas that PAVO applies to calculate quantum catch and excitation for this model. I've been looking in the paper of Troje 1993, but I can't figure out the formulas. Thanks in advance!
Thomas White
@thomased

Heya. The quantum catch is calculated however you like in vismodel(), then all colspace() is doing for the categorical model is calculating the opponent channels Troje hypothesises (e.g. Fig. 5). i.e; x = R7y - R8y, y = R7p - R8p (or vice versa, can't recall) . It's a very straightforward model!

The output also returns typical 'continuous' measures of hue (h.theta), saturation (r.vec) etc. for the space because they can be useful, and in light of more recent evidence questioning the categorical nature of the it all.

Melissa León
@leonosper_melissa:matrix.org
[m]
I should explain myself better. I ended up with an excel for the categorical model of Troje (Table S2 from An et al 2018), but I can't get the same output in PAVO and in the excel, and I've realized that the difference must be in the quantum catch. In excel and in PAVO I get hiperbolic quantum catch, but excitations don't match. I want to know how PAVO calculate the Qi for the posterior hiperbolic qcatch, and try to find the difference between the excel and PAVO.
Thomas White
@thomased

Ah okay, cool cool. Well I'd have to have a poke through An et al. sometime (what's the paper sorry? Can't seem to find it at a glance), but I'm a little snowed under atm so will have a good look when I can soon. Otherwise feel free to have a wander through vismodel() itself if you like? https://github.com/rmaia/pavo/blob/master/R/vismodel.R. It's reasonably well commented & navigable.

The hyperbolic transform is is just Q/(Q+1) though, with Q calculated as per usual (illum x receptors x stimulus or background). The input spectra are an obvious source of variation, but I'm guessing you're using the same set for the comparison. Otherwise yep, I'll have to have a look at their spreadsheet internals sometime ~soon.

Melissa León
@leonosper_melissa:matrix.org
[m]
Thanks! You can find the paper here: https://journals.biologists.com/jeb/article/221/22/jeb184788/20736/The-yellow-specialist-dronefly-Eristalis-tenax?searchresult=1 I will wander through vismodel(), and yes, I'm using the same data set, and the same sensitivities using sensemodel() (the paper is about Eristalis tenax), and illumination and background.
Thomas White
@thomased
Cheers!
Andreia Figueiredo Dexheimer
@andreiafig_twitter
Hi! I'm having the same problem @luizafpassos_twitter described on Feb 08. I keep getting the same error message (Error: package or namespace load failed for ‘pavo’ in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]]):
there is no package called ‘misc3d’) and when I try to install "misc3d" I get the exact same error message described by @luizafpassos_twitter . I am using a MacBook, so tried running xcode-select --install on my terminal, and the code runs, but it did not solve my problem. Any advice on how to get pavo running?
Andreia Figueiredo Dexheimer
@andreiafig_twitter
It took a few hours of digging and trying things out, but I had to install X Quarts (https://www.xquartz.org/) first and then install the misc3d package so that I could install and open pavo with no errors. Hope this is helpful to someone :)
Thomas White
@thomased
Ah, glad to hear it, and thanks @andreiafig_twitter! I'll take note :)
Andreia Figueiredo Dexheimer
@andreiafig_twitter

Hi! I have another quesiton, this time about the function "colspace". Here is some context: I am using pavo to model the visual system of the orchid bee Euglossa dilemma. I uploaded my photoreceptor measurements and lens transmission measurements and used "vismodel" to create a visual model for my species. Things seem to work well, but when I use "colspace" I get a warning message, and I think that is messing things up when I try to plot my data using the color hexagon.

Here is my code:

edilemma_model <- vismodel(rspecdata = edil_spectra, visual = edilemma, trans = edil_transmission, relative = FALSE, vonkries = TRUE)

But when I use

edil_colorspace <- colspace(edilemma_model, space = "hexagon")

I get this error: 1: Quantum catches are not hyperbolically transformed, as required for the hexagon model. This may produce unexpected results.

And I am not sure what it means exactly. Any thoughts or suggestions are highly appreciated!

Thomas White
@thomased
Hi @andreiafig_twitter — sounds cool! That just means you haven't specified qcatch = 'Ei' in your call to vismodel(). That's the 'hyperbolic transform' of receptor catches, which the hexagon model uses as part-and-parcel of its calculations (have a look at the help docs for a sense of what it's doing, or the original reference of course for a slightly longer explanation). I'll tweak that warning message to make it more explicit too though, so it directs you to the specific solution if desired — sorry about that!
Andreia Figueiredo Dexheimer
@andreiafig_twitter
It worked, thank you so much! :) I did look at the help docs but I was a little bit confused, but now it makes more sense! By the way, the help docs are super helpful!!!
Thomas White
@thomased
Brilliant! No worries — glad to hear it.
tarynmueller
@tarynmueller
Hi- I'm struggling to import files. I have a folder that I direct to, and when I attempt to run it, it begins importing, but returns: "471 files found; importing spectra:
Warning message:
File import failed.
Check input files and function arguments. " I've tried a bunch of different arguments and I'm not sure how to fix this.
Hugo Gruson
@Bisaloo
Hi @tarynmueller, sorry to hear this. Can you send me some of these files by email (hugo.gruson@normalesup.org) so I can have a look please?
EliF777
@EliF777
Hi! I'm having some trouble with the spec2rgb functionality. I keep getting an error message which states that "wavelength range in spectra and visual system data do not match," despite the fact that all of the specified wavelengths are between 400-700. Any ideas what could be going wrong?
Hugo Gruson
@Bisaloo
Hi @EliF777, my first guess would be that even though you have the same wavelength ranges, you don't have the same wavelength increment steps. Do you have a value for each nanometer? If not, you could convert your rspec object with as.rspec(x, interp = TRUE).
Thomas White
@thomased

Hi @EliF777, just adding a guess to @Bisaloo's suggestion, it might also just be a little bug arising from the fact that spec2rgb() uses vismodel() internally with some built-in illuminant and viewer sensitivity (CIE) data. But they're both 300-700, so it will be unhappy when you feed it a 400-700 spec. It's just one of those edge-cases we didn't think to test for.

To check, just interpolate your specs to 300-700 using as.rspec(your_specs, lim = c(300, 700)) and see if it works then. I'll look at making spec2rgb() a little more flexible too, and/or at least a bit more informative when failing. Thanks!

EliF777
@EliF777
@Bisaloo @thomased Thanks for the help guys! Unfortunately, neither of these fixes seem to have done it, but it does seem that the problem is caused by spec2rgb() using vismodel(). I do have values for each nanometer but the increments are inconsistent... Is there a way to make this still work? Or are standard increments required?
EliF777
@EliF777
@Bisaloo Is it possible to set the interp parameter in the getspec() function? I realize that the data has also been warped while being imported because the wavelengths are non-integers but getspec() places them into 1-nm bins
Thomas White
@thomased
@EliF777 Hmm. I'm sure it's solvable - do you mind just sending along a snippet of the data + code for us to reproduce it? Typically the fastest way to get to the bottom of things. thomas.white026@gmail.com / hugo.gruson@normalesup.org
Javier Abalos
@abalosaurus_twitter
Hi! I am writing you to ask for guidance on analysis of spectrophotometric data with a repeated measures design. Specifically, what we have is two different types of data for two different studies (iridescence and ontogenetic changes). Our interest is to assess colour changes comparing the reflectance spectra at a within-individual level (repeated measures design), obtaining both a statistic that evaluates their significance of the colour differences and an estimate of their distance in JNDs (and the uncertainty around this distance). I tried to adapt the script published [title] (https://tomwhite.io/docs/Maia_&_White_2018_supplement.html) in approach 1. I also published a question in crossvalidated [tilte] (https://stats.stackexchange.com/questions/558165/repeated-measures-permanova-and-mean-group-differences-for-spectral-data-using-p) where you can find the whole script and more details. I can send you the data if that helps. Thanks in advance, Javier

My main problem right now is being able to obtain JNDs (with confidence intervals) between every pair of angles, although based exclusively on within-individual distances. The problem is that I don't know how to code the "by=" argument in order for the bootcoldist function to do what I want:

boot <- bootcoldist(vis, by=pred$angle, n=c(1,1,1,4), weber=0.05, weber.achro=0.05)
`

Thank you!

Javier Abalos
@abalosaurus_twitter
@Bisaloo @thomased I would also appreciate any help to obtain adjusted p-values from the repeated measures Permanova (pairwise.adonis function). Thank you very much!
Thomas White
@thomased
Hi @abalosaurus_twitter, nice to hear from you. I'm still on leave at the moment and am mostly away from a computer, but just wanted to drop a quick note to say getting back to you is high on my todo list (& I got your email, thanks), so I'll have think & poke around shortly. Chat soon! Take care in the meantime.
Javier Abalos
@abalosaurus_twitter
@thomased Thank you very much for your answer! Enjoy the rest of your leave!
Javier Abalos
@abalosaurus_twitter
@thomased @Bisaloo Hi! I would like to know if there is a way to access the dataframe of relative cone sensitivities used by the function vismodel when you specifi the argument visual="cie2" or visual="avg.v". I would like to create a graph overlapping cone sensitivities to the reflectance spectra of some stimuli but I cannot find a way to "extract" this dataframes form pavo! Thank you very much in advance, Javier
Hugo Gruson
@Bisaloo

Hi @abalosaurus_twitter :wave:, yes, you should be able to get them with the sensdata() function. For the specific cases you mention, you can use:

sensdata(visual = "cie2")
sensdata(visual = "avg.v")

You're not the first person to ask this question so I've added a small hint in the documentation of vismodel(): http://pavo.colrverse.com/reference/vismodel.html#see-also-1. It'll hopefully point people in the right direction from now on. But please let us know if you have other suggestions on how we could make it easier to discover.

Javier Abalos
@abalosaurus_twitter
Thank you very much!! This works perfectly, and I think the addittion in the documentation will help people to find it more easily
juandemedel
@juandemedel
Hello, I've been plotting spectral data but after use procspec to smooth spectral curve I've got an x-axis displacement of the smoothed curve. Would you please give me some advice?
Hugo Gruson
@Bisaloo
Hi @juandemedel, could you please share an example dataset (you can send it to thomas.white026@gmail.com / hugo.gruson@normalesup.org) and the code you use to see what you are describing?
juandemedel
@juandemedel
Thank you so much Doctor Hugo Gruson. Doctor Thomas White just showed me how to fix this issue on GitHub, here: rmaia/pavo#234
juandemedel
@juandemedel
Hello dear community, I've been plotting PCA loadings and wavelengths. However, I do not understand why one has to use the option opt = c("bin") in procspec(). Is mandatory to use bin? if so, why?.
juandemedel
@juandemedel
Hello dear community. In The pavo handbook: studying biological colouration in R; Chapter 2; 2.2.3 Binning and PCA Analysis of Spectral Shape I saw that with spec.bin <- procspec(sppspec, opt = c("bin", "center")) and with pca1 <- prcomp(spec.bin, scale. = TRUE) data are centered twice since prcomp's default method sets center = TRUE. Thereby, centering once or twice gives me different loadings-wavelengths plots. Would you please advise me on whether I have to use centering once or twice to obtain the right loading-wavelengths plot?.
amadorkane
@amadorkane
My research student asked me to poll folks on gitter: "How can I include the names of the spectra txt files as labels for plots of the mean reflectance curves and as labels for the corresponding points on a color hexagon plot? (or triangular colorspace plot.) I would like to compare the colors of different flower petals. Without labels showing which dot represents which flowers, it is difficult to interpret my data. "
Hugo Gruson
@Bisaloo
Hi @amadorkane, thanks for reaching out.
  • for the labels on aggplot(), as documented the relevant section of the pavo handbook, you can display the legend simply by setting the legend argument to TRUE
  • for hexplot()/triplot(), I don't think we currently have an integrated way to do this. You best bet is probably to use the legend() base R function or add the legend in post-production
1 reply
Rafael Maia
@rmaia
[Tom White, pavo] Hi! Its importance depends a bit on which model you’re using, but if you’d like to normalise any spectrum (including your converted irradiance) you can use procspec(your_spectra, opt = c('min', 'max').
Thomas White
@thomased
Weird - that message was from me (Tom). Feel free to email if you like too - thomas.white@sydney.edu.au, since gitter isn't used so much.