Closed thomased closed 1 year ago
Awesome, many thanks for those edits & your thoughts. I'm with you on all points — I'll keep adjusting things along those lines and we can see how we like it.
Latest examples, from the help docs:
# Single ideal 'grey' reflectance spectrum, with 50% reflectance across 300 - 700 nm.
reflect0 <- simulate_spec(ylim = c(0, 50))
# Single sigmoidal spectrum, with a low-to-high inflection at 550 nm.
reflect1 <- simulate_spec(wl_inflect = 550)
# Single Gaussian spectrum, with a peak at 400 nm
reflect2 <- simulate_spec(wl_peak = 400)
# Combination of both Gaussian (with peak at 340 nm) and sigmoidal (with inflection
# at 560 nm)
reflect3 <- simulate_spec(wl_inflect = 560, wl_peak = 340)
# Double-Gaussian peaks of differing widths
reflect4 <- simulate_spec(wl_peak = c(340, 560), width_gauss = c(12, 40))
# Complex spectrum with single sigmoidal peak and multi-Gaussian peaks
reflect5 <- simulate_spec(wl_inflect = 575, wl_peak = c(340, 430), width_gauss = c(20, 60))
# Merge and plot
spectra <- Reduce(merge, list(reflect0, reflect1, reflect2, reflect3, reflect4, reflect5))
plot(spectra, lty = 1:5)
# Simulate a set of Gaussian reflectance curves with peaks varying between 400-600nm
# in increments of 10, then combine into a single rspec object, and plot the result
peaks <- seq(400, 600, 10) # Peak locations
reflectances <- lapply(seq_along(peaks), function(x) simulate_spec(wl_peak = peaks[x])) # Simulate
reflectances <- Reduce(merge, reflectances) # Combine
plot(reflectances) # Plot
# Simulate a set of Gaussian reflectance curves with a single peak at 500 nm, but
# with maximum reflectance varying from 30 to 90% in 10% increments, then combine
# into a single rspec object, and plot the result
ymax <- lapply(seq(30, 90, 10), function(x) c(0, x)) # Varying reflectance maxima
reflectances2 <- lapply(ymax, function(x) simulate_spec(wl_peak = 500, ylim = x)) # Simulate
reflectances2 <- Reduce(merge, reflectances2) # Combine
plot(reflectances2) # Plot
# To simulate non-reflectance spectra (like irradiances or radiances), it's often useful
# to explore more 'extreme' parameters. Here's a simple example which simulates
# natural daylight, as represented by the D65 standard daylight spectrum.
D65_real <- procspec(sensdata(illum = 'D65'), opt = 'smooth') # Official D65 daylight spectrum
D65_sim <- simulate_spec(wl_peak = 400,
width_gauss = 1300,
skew_gauss = 10,
ylim = c(0, 1)) # Simulated D65
cor.test(D65_real$D65, D65_sim$spec_p400) # >0.99 correlation
plot(merge(D65_real, D65_sim), lty = 1:2, ylab = 'Irradiance (%)') # Merge and plot the two spectra
Absolutely no rush at all @Bisaloo, but if you want to cast another eye over it sometime it'd be appreciated. I think I'm basically happy with where it's at - just about ready to merge. Can always do some further fine-tuning before the next release of course. And happy to hear alternative views on any of the above points - I've just jotted down my thinking.
Fix https://github.com/rmaia/pavo/issues/151. Moving discussion here from #185 because I started from scratch after completely forgetting that you'd already had a go at it @Bisaloo, then tried to merge them & screwed everything up, so just started again here (I'll learn git one day...).
Stuff to to discuss (partly from #185):
pavo
, or would there value in thinking of a little package dedicated to simulating 'natural' spectra at this early stage? Could also split off and expandsensmodel()
frompavo
, and explore possibility of functionality for radiance and/or irradiance spectra (trickier...). So it could be a package for simulating 'biological' reflectance, absorbance/absorbtance, radiance (maybe), or irradiance spectra? Alternatively, could add a few new related functions to pavo. Likesim.reflect()
,sim.absorb()
,sim.irrad()
or something. A: Keep in pavo for immediacy & convenience benefits (& lack of strong reason not to at this stage), though reserve the right to roll into its own package for fun later on.simulate_spec()
orsim_spec()
more consistent with current norms? I'd reach for the former since it's not that much longer, but is more clear. Should it besimulate_reflect()
in case of futuresimulate_irrad
and the like though? Or I guess you could use this to simulate irradiance spectra of a sort already - maybe it's more a case of fleshing out the examples to show as much. In which casesimulate_spec
is sensible. Added an irradiance example to the docs - I'm leaning toward keepingsimulate_spec
as the name.ylim
. Added example to support. 5b43030f0624fa4523548d03d6134241b02aeb82ylim()
range. This is fine, and does what you'd expect when the changes in reflectance are separated (like a bell curve in the UV, and sigmoid in the red, in the example below). But when changes are close together, the resulting curve can be hard to predict, and the 'shape' of the underlying constituent curves isn't preserved. Various alternatives, but then the y range is often blown out. I think it's ultimately a trade-off, but need to think about & understand it better. A: Agree I think current behaviour is what you'd most likely expect. May revise on further testing/playing, but happy for now.ylim()
? A: I'm currently inclined to keep it (still open to removing though). It'd make simulations of luminance/brightness variation simpler. i.e. users could lapply() through a set ofylim()
s to simulate certain kinds of limited-view iridescence, without having to manually renormalise along the way. The direction of any sigmoidal curve is also now controlled by this, as is the maximum of the (default) 'ideal' spectrum, so I'm increasingly inclined to keep it. Added an example - 2fc8a4966af84299cf4c4107bcf9376c6222916csensmodel()
does)? A: Added unique naming convention, which includes information on specified inflection points and/or peaks. 3cfca35c0166006aed168818d7c08c20f9bc478c.ylim()
, such thatylim = c(0, 100), wl_inflect = 550
would generate a low-to-high curve, whereasylim = c(100, 0), wl_inflect = 550
would generate a high-to-low? A: Can't see any harm? Done here - 494c4f2e0aca0ac68f1c3b7a1bde54c8035b320bskew_gauss
parameter so Gaussian curves are drawn from skew-normal distribution. Useful for simulating convincing irrad/rad spectra - https://github.com/rmaia/pavo/pull/247/commits/7ba9c127dfb7f35502317f00ddd9de9c5646dab1Thoughts welcome!
Working example: