| Title: | Design Complex Light Regimes |
|---|---|
| Description: | A system for accurately designing complex light regimes using LEDs. Takes calibration data and user-defined target irradiances and it tells you what intensities to use. For more details see Vong et al. (2025) <doi:10.1101/2025.06.06.658293>. |
| Authors: | Gina Vong [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-3913-7667>) |
| Maintainer: | Gina Vong <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 1.0.0 |
| Built: | 2026-05-22 07:18:24 UTC |
| Source: | https://github.com/ginavong/lightfitr |
Example calibration data
calibrationcalibration
A data frame with 12 columns:
File that the raw data came from
The time when a given measurement was taken
LED channel being calibrated at that timepoint
Intensity the light is set to
The wavelength this row describes
The irradiance measured at that wavelength by the spectrometer
<https://github.com/ginavong/2024_LightFitR_MethodsPaper/blob/master/data/heliospectra_measurements/calibration/Apollo_Calib_20240827/Apollo_calibration_annotated_20240827.Rda>
Check that the intended irradiances are acheivable by the lights
checkRange( intended_irradiance, calibration_leds, calibration_wavelengths, calibration_intensities, calibration_irradiances )checkRange( intended_irradiance, calibration_leds, calibration_wavelengths, calibration_intensities, calibration_irradiances )
intended_irradiance |
Matrix of intended irradiances to be checked. Each row corresponds to an LED channel. |
calibration_leds |
A numeric vector of LED values from calibration, mapping to intensities and irradiances (i.e. the same length) |
calibration_wavelengths |
A numeric vector of wavelengths from calibration, corresponding to intensities and irradiances |
calibration_intensities |
A numeric vector of intensities (heliospectra units) from calibration |
calibration_irradiances |
A numeric vector of measured irradiances (any units, as long as it is consistently used) from calibration |
Boolean: TRUE = pass, FALSE = fail
calib <- LightFitR::calibration irradiances <- LightFitR::target_irradiance checkRange(irradiances, calib$led, calib$wavelength, calib$intensity, calib$irradiance)calib <- LightFitR::calibration irradiances <- LightFitR::target_irradiance checkRange(irradiances, calib$led, calib$wavelength, calib$intensity, calib$irradiance)
Matrix of closest intensities for example purposes. Generated from 'target_irradiance'
example_closestexample_closest
A matrix with 9 rows and 10 columns: each row represents an LED channel and each column represents an event
Matrix of random intensities for example purposes
example_intensitiesexample_intensities
A matrix with 9 rows and 10 columns: each row represents an LED channel and each column represents an event
Example regime matrix
example_regimeexample_regime
A matrix with 13 rows and 10 columns:
time in HH:MM:SS format
The hour of the event
The minute of the event
The second of the event
Intensity at 380nm LED channel
Intensity at 400nm LED channel
Heliospectra DYNA matrices should have 9 rows (1 for each LED channel) and up to 150 columns (max number of events that Heliospectra DYNA can store)
helio.checkFormat(check_matrix)helio.checkFormat(check_matrix)
check_matrix |
Matrix to be checked. Rows correspond to LEDs and columns are events / timepoints. |
Vector of booleans: TRUE = pass, FALSE = fail
matrix_to_check <- LightFitR::target_irradiance helio.checkFormat(target_irradiance)matrix_to_check <- LightFitR::target_irradiance helio.checkFormat(target_irradiance)
Format regime_matrix for csv output that Heliospectra lights can parse
helio.csv_schedule(regime_matrix, filename)helio.csv_schedule(regime_matrix, filename)
regime_matrix |
Matrix containing light regime, as generated by makeRegime |
filename |
Character. Filename to export to |
Matrix formatted for Heliospectra lights csv
tempfile_name = tempfile(fileext='.csv') helio.csv_schedule(LightFitR::example_regime, tempfile_name)tempfile_name = tempfile(fileext='.csv') helio.csv_schedule(LightFitR::example_regime, tempfile_name)
Congratulations! You've found the easter egg function!
helio.disco(filename, format = c("csv", "json"))helio.disco(filename, format = c("csv", "json"))
filename |
Character. Filename to export to |
format |
Character. Which format to export to? csv or json. Use extensions '.csv' or '.txt' |
This writes a schedule for Heliospectra DYNA lights which randomly changes colour every second for a fun disco effect. The disco will last until the Heliospectra runs out of memory (150 events), so you can get 2 min 30s of disco out of your expensive lights... Enjoy!
Disco schedule file for the heliospectra
tempfile_name = tempfile(fileext='.txt') helio.disco(tempfile_name, format='json')tempfile_name = tempfile(fileext='.txt') helio.disco(tempfile_name, format='json')
Data about the heliospectra DYNA LED channels
helio.dyna.ledshelio.dyna.leds
A data frame with 9 rows and 3 columns:
Name of the LED channel
Wavelength of the LED channel
Colour of the LED channel
<https://heliospectra.com/led-grow-lights/dyna/>
Maximum number of events programmable onto heliospectra
helio.eventLimithelio.eventLimit
Integer representing maximum allowable events
Format regime_matrix for json output that Heliospectra lights can parse
helio.json_schedule(regime_matrix, filename)helio.json_schedule(regime_matrix, filename)
regime_matrix |
Matrix containing light regime, as generated by makeRegime |
filename |
Character. Filename to export to |
Character in json format that Heliospectra can parse
tempfile_name = tempfile(fileext='.txt') helio.csv_schedule(LightFitR::example_regime, tempfile_name)tempfile_name = tempfile(fileext='.txt') helio.csv_schedule(LightFitR::example_regime, tempfile_name)
Internal function. Find the intensities corresponding to the closest irradiance match between intended and calibration.
internal.closestIntensities( irradiance_matrix, calibration_df, peaks = LightFitR::helio.dyna.leds$wavelength )internal.closestIntensities( irradiance_matrix, calibration_df, peaks = LightFitR::helio.dyna.leds$wavelength )
irradiance_matrix |
Matrix of intended irradiances. rows = leds and columns = events |
calibration_df |
Dataframe of calibration data generated by internal.calibCombine |
peaks |
Vector of length 8 or 9. Containing wavelengths at which each LED peaks. |
Matrix of closest intensities, in the same format as 'irradiance_matrix'
# Format calibration data correctly calib <- LightFitR::calibration[, c(3, 5, 4, 6)] # Run function internal.closestIntensities(LightFitR::target_irradiance, calib)# Format calibration data correctly calib <- LightFitR::calibration[, c(3, 5, 4, 6)] # Run function internal.closestIntensities(LightFitR::target_irradiance, calib)
This is a wrapper function that carries out multiple steps:
1. Calculate closest intensities
2. Predict the intensities to use to achieve the target irradiance (via a system of linear equations or non-negative least squares)
3. Tidy the intensities (rounding to integer, keep within the range of intensities that the lights can be set to)
4. Format the intensities and timestamps into a human-readable regime matrix
makeRegime( timeVector_POSIXct, irradiance_matrix, calibration_leds, calibration_wavelengths, calibration_intensities, calibration_irradiances, peaks = LightFitR::helio.dyna.leds$wavelength, method = "nnls" )makeRegime( timeVector_POSIXct, irradiance_matrix, calibration_leds, calibration_wavelengths, calibration_intensities, calibration_irradiances, peaks = LightFitR::helio.dyna.leds$wavelength, method = "nnls" )
timeVector_POSIXct |
Vector of schedule timepoints in POSICxt format |
irradiance_matrix |
Matrix of intended irradiances. rows = leds and columns = events |
calibration_leds |
A numeric vector of LED values from calibration, mapping to intensities and irradiances (i.e. the same length) |
calibration_wavelengths |
A numeric vector of wavelengths from calibration, corresponding to intensities and irradiances |
calibration_intensities |
A numeric vector of intensities (heliospectra units) from calibration |
calibration_irradiances |
A numeric vector of measured irradiances (any units, as long as it is consistently used) from calibration |
peaks |
Vector of length 8 or 9. Containing wavelengths at which each LED peaks. |
method |
Use 'nnls' (non-negative least squares) or 'sle' (system of linear equations) |
Matrix with light regime needed to program the lights
NNLS and SLE largely predict the same intensities, except in outlier cases. The default is NNLS, but if your predicted intensities end up being very far off, try SLE.
# Prep variables calib <- LightFitR::calibration times <- LightFitR::time_vector target_irradiance <- LightFitR::target_irradiance # Run function makeRegime(times, target_irradiance, calib$led, calib$wavelength, calib$intensity, calib$irradiance)# Prep variables calib <- LightFitR::calibration times <- LightFitR::time_vector target_irradiance <- LightFitR::target_irradiance # Run function makeRegime(times, target_irradiance, calib$led, calib$wavelength, calib$intensity, calib$irradiance)
Use non-linear least squares to interpolate intensities
nnls_intensities( irradiance_matrix, closest_intensities, calibration_leds, calibration_wavelengths, calibration_intensities, calibration_irradiances, peaks = LightFitR::helio.dyna.leds$wavelength )nnls_intensities( irradiance_matrix, closest_intensities, calibration_leds, calibration_wavelengths, calibration_intensities, calibration_irradiances, peaks = LightFitR::helio.dyna.leds$wavelength )
irradiance_matrix |
Matrix of intended irradiances. rows = leds and columns = events |
closest_intensities |
Matrix of closest intensities, generated by 'internal.closestIntensities'. Same format as 'irradiance_matrix' |
calibration_leds |
A numeric vector of LED values from calibration, mapping to intensities and irradiances (i.e. the same length) |
calibration_wavelengths |
A numeric vector of wavelengths from calibration, corresponding to intensities and irradiances |
calibration_intensities |
A numeric vector of intensities (heliospectra units) from calibration |
calibration_irradiances |
A numeric vector of measured irradiances (any units, as long as it is consistently used) from calibration |
peaks |
Vector of length 8 or 9. Containing wavelengths at which each LED peaks. |
Matrix of intensities to set the lights to, to achieve desired irradiances
# Prep variables target_irradiance = LightFitR::target_irradiance closest = LightFitR::example_closest calib = LightFitR::calibration # Run the function nnls_intensities(target_irradiance, closest, calib$led, calib$wavelength, calib$intensity, calib$irradiance)# Prep variables target_irradiance = LightFitR::target_irradiance closest = LightFitR::example_closest calib = LightFitR::calibration # Run the function nnls_intensities(target_irradiance, closest, calib$led, calib$wavelength, calib$intensity, calib$irradiance)
Read a heliospectra script (json format) into a matrix.
read.helio_json(helio_script)read.helio_json(helio_script)
helio_script |
File (.txt or .json) containing heliospectra regime script |
Matrix containing the regime encoded by the Heliospectra script
example_file <- system.file("extdata", "example_json_schedule.txt", package = "LightFitR", mustWork = TRUE) read.helio_json(example_file)example_file <- system.file("extdata", "example_json_schedule.txt", package = "LightFitR", mustWork = TRUE) read.helio_json(example_file)
Use a system of linear equations to calculate intensities
sle_intensities( irradiance_matrix, closest_intensities, calibration_leds, calibration_wavelengths, calibration_intensities, calibration_irradiances, peaks = LightFitR::helio.dyna.leds$wavelength )sle_intensities( irradiance_matrix, closest_intensities, calibration_leds, calibration_wavelengths, calibration_intensities, calibration_irradiances, peaks = LightFitR::helio.dyna.leds$wavelength )
irradiance_matrix |
Matrix of intended irradiances. rows = leds and columns = events |
closest_intensities |
Matrix of closest intensities, generated by 'internal.closestIntensities'. Same format as 'irradiance_matrix' |
calibration_leds |
A numeric vector of LED values from calibration, mapping to intensities and irradiances (i.e. the same length) |
calibration_wavelengths |
A numeric vector of wavelengths from calibration, corresponding to intensities and irradiances |
calibration_intensities |
A numeric vector of intensities (heliospectra units) from calibration |
calibration_irradiances |
A numeric vector of measured irradiances (any units, as long as it is consistently used) from calibration |
peaks |
Vector of length 8 or 9. Containing wavelengths at which each LED peaks. |
Matrix of intensities to set the lights to, to achieve desired irradiances
#' # Prep variables target_irradiance = LightFitR::target_irradiance closest = LightFitR::example_closest calib = LightFitR::calibration # Run the function sle_intensities(target_irradiance, closest, calib$led, calib$wavelength, calib$intensity, calib$irradiance)#' # Prep variables target_irradiance = LightFitR::target_irradiance closest = LightFitR::example_closest calib = LightFitR::calibration # Run the function sle_intensities(target_irradiance, closest, calib$led, calib$wavelength, calib$intensity, calib$irradiance)
Matrix of random target irradiances for example purposes
target_irradiancetarget_irradiance
A matrix with 9 rows and 10 columns: each row represents an LED channel and each column represents an event
Example timepoints for events
time_vectortime_vector
A vector of length 10 with timepoints in POSIXct format
Writes to json or csv format
write.helioSchedule(regime_matrix, filename, format = c("csv", "json"))write.helioSchedule(regime_matrix, filename, format = c("csv", "json"))
regime_matrix |
Matrix containing light regime, as generated by makeRegime |
filename |
Character. Filename to export to |
format |
Character. Which format to export to? csv or json. Use extensions '.csv' or '.txt' |
Heliospectra schedule file in either the csv or json format
tempcsv_name = tempfile(fileext='.csv') write.helioSchedule(LightFitR::example_regime, tempcsv_name, format='csv') temptxt_name = tempfile(fileext='.txt') write.helioSchedule(LightFitR::example_regime, temptxt_name, format='json')tempcsv_name = tempfile(fileext='.csv') write.helioSchedule(LightFitR::example_regime, tempcsv_name, format='csv') temptxt_name = tempfile(fileext='.txt') write.helioSchedule(LightFitR::example_regime, temptxt_name, format='json')