Camera objectives for digital UV photography

Differences in the transmission spectrum

equipment
lenses
Author

Pedro J. Aphalo

Published

2018-05-13

Modified

2023-04-14

Keywords

objectives, filters, ultraviolet, spectra

Code
# setup
library(knitr)
library(tidyverse)
library(ggspectra)
library(patchwork)
library(photobiology)
library(photobiologyWavebands)
library(photobiologyLEDs)
library(photobiologyFilters)

my.fig.width <- 7
my.fig.height <- 3.5

knitr::opts_chunk$set(
  fig.width = my.fig.width, fig.height = my.fig.height, dev = "svg", out.width = "95%"
)
theme_set(theme_bw() + theme(legend.position = "top")) 
Note

I have updated this page on 2023-04-14 when transferring it to Quarto and again on 2023-04-23. I have not added new data but the plots are built in R within the R markdown source file. The page includes the listing of the R code used to create all plots. Text has been slightly revised. Most of the content of this page was earlier in a file linked to a WordPress page. Now the contents formerly in a separate file are included in the page. The text sections have been reorganized and the design of some of the figures modified.

Introduction

Lenses

I tested prime lenses only, including several suitable for macro and close-up photography. They include designs ranging from 1960’s to 2010’s. Older lenses were designed for full-frame cameras while the modern ones I tested are designed for 4/3 sensors (Figure 1). In addition to these lenses, I tested a Zhongyi Lens Turbo II EF-M43 focal reducing adapter, which includes optical elements with the opposite effect to those in a tele-converter.

G.Zuiko 28mm 1:3.5 OM

G.Zuiko 35mm 1:3.5 OM

Zuiko 50mm 1:3.5 MACRO OM

Zuiko 50mm 1:3.5 MACRO OM extended

E.Zuiko 100mm 1:2.8 OM

Nikon 24mm 1:2.8 AIS F

Soligor 35mm 1:3.5 M42, on adapter

Hanimex 35mm 1:3.5 MD, on adapter

Hanimex 35mm 1:3.5 MD, back

Zuiko Digital 50mm 1:2.0 Macro FT

M.Zuiko Digital 25mm 1:1.8 MFT

M.Zuiko 60mm 1:2.8 Macro MFT

Sigma 19mm 1:2.8 MFT

Sigma 30mm 1:2.8 MFT

Sigma 60mm 1:2.8 MFT

Sigma 30mm 1:1.4 MFT

Pinhole Pro 26 mm 1:32 MFT
Figure 1: Photographs of several of the lenses tested. More details are provided below (Table 1). Click on any photograph to open a gallery at higher resolution.

I tested nearly 20 objectives, of which 11 were released after year 2000 (8 of which are currently in production) and the remaining ones are designs from the 1960’s, 1970’s and 1980’s and manufactured in the 1970’s and 1980’s (Table 1). One of the objectives tested is a pinhole, i.e., has no glass. All the OM Zuiko objectives are early production types, in “silver nose” livery (later “black nose” versions of the same objectives are thought to be all multi-coated) (described at the “Olympus Shared Resources” web site). The Soligor 35 mm and the Hanimex 35 mm have a coating giving blue reflections. They are of the type described as being based on the same optical design at the Petri Kuribayashi “Kuri”, Kyoei, Acall and similar (Hanimex and Soligor described by Savazzi n.d.). The barrels are different. The four Sigma objectives tested in their MFT (micro four-thirds mount) version are also available in Sony E mount (Sigma 19 mm described by Savazzi n.d.). All Olympus OM objectives were tested mounted on the E-M1 with a Novoflex MFT/OM adapter. The Soligor objective has an M42 mount, and was mounted on the E-M1 with a Fotasy M42 to MFT adapter with focusing helicoid. The Hanimex objective has a Minolta MD mount and was tested mounted on MD to MFT adapter with focusing helicoid (unbranded). The Nikkor lens was mounted using a Fotodiox adapter. The Digital Zuiko was mounted using an Olympus MMF-3 adapter.

The light transmission properties of the glass or plastic from which optical elements are made of, and the length of the light path through these materials affect the transmittance of an objective. In addition, at each air-glass or air-plastic interface some light is reflected. Lens elements are frequently arranged in groups with elements affixed together, in which case the material used to affix the elements together will also affect the overall transmittance. From this we can surmise that the more complex a lens design is, the less likely it is to have high transmittance outside the range of wavelengths it was designed for.

Reflections are controlled by means of anti-reflection (AR) coatings, of which there are many different variations. Coatings can be optimized for different wavelengths, and the material used for coatings can potentially absorb radiation. Single anti-reflection coatings usually are made of magnesium fluoride, which is transparent to ultraviolet radiation. However, AR coatings can increase reflection outside the target range of wavelengths for which they are designed. In addition, objectives may have different coatings on different lens-element surfaces, and rarely, even in modern designs all glass-air surfaces internal to an objective are coated. So although, testing/screening old objectives of simple design, lacking AR coating, or having only single AR, is more likely to yield good accidental UVA-capable objectives, it is not impossible that some newer simple objective designs are also UVA-capable by accident. In general good prime objectives (single focal length) with moderate maximum aperture can be produced using much simple designs than zooms or objectives with large maximum apertures. In addition, primes of very short focal length, tend to use complex designs. In Table 1 available information on the optical design, coating and year of introduction and/or production are given for all the objectives tested.

Code
# read data
read_csv("objectives.csv", comment = "#") %>%
  mutate(objective = factor(objective),
         mount = toupper(mount),
         vis.factor = signif(vis.factor / 1.367, 3L)) ->
  objectives.df

kable(arrange(objectives.df, introduction))
Table 1: Details about the objectives tested. Column “objective” gives the abbreviated code used in figures to distinguish the objectives. The year of introduction to the market is when know, accurate, while the year of production is in several cases estimated from the date of purchase, so some of the newer objectives could have been manufactured before the date given, but never later. The values in column “vis.factor” as estimated differences in transmittance assessed by the response of the red sensor channel to a white target illuminated with warm-white LEDs. The Soligor objective is dated based on the serial number using the tables at the Apotelyt site as a guide.
objective mount make focal.length aperture.max elements groups coating sn introduction produced vis.factor filter.size FFD
k35lm M39 W.Acall.Kyoei 35 3.5 6 4 single 10008 195x NA NA 42 28.80
z50 OM Zuiko 50 3.5 5 4 single 124064 1972 NA 0.860 49 46.00
z200 OM F.Zuiko 200 5.0 6 5 multiple 122483 1972 198x 0.860 49 46.00
z135 OM E.Zuiko 135 3.5 5 5 single 104496 1972 1972 0.820 49 46.00
z100 OM E.Zuiko 100 2.8 5 5 single 139257 1972 NA 0.878 49 46.00
z35 OM G.Zuiko 35 2.8 7 6 single 153937 1972 NA 0.732 49 46.00
z28 OM G.Zuiko 28 3.5 7 7 single 116979 1972 NA 0.732 49 46.00
z38 OM/RMS Zuiko Macro 38 3.5 5 4 single 200322 1972 NA 0.934 32p 46.00
nk24.28 F.AI Nikkor 24 2.8 9 9 multiple 676270 197x NA 0.640 52 46.50
dz50 FT D.Zuiko 50 2 11 10 multiple 010210916 2003 2008 0.985 52 38.67
mz12.25 MFT M.Zuiko 12-50 3.5-6.3 10 9 multiple ABPA05134 2011 NA NA 52 19.25
mz45.18 MFT M.Zuiko 45 1.8 9 8 multiple ABMA13160 2011 NA 0.760 37 19.25
mz60.28 MFT M.Zuiko 60 2.8 13 10 multiple ABQA20394 2012 2015 1.130 46 19.25
s30.28 MFT Sigma.DN.A 30 2.8 7 5 multiple 50107246 2013 NA 0.732 46 19.25
s19.28 MFT Sigma.DN.A 19 2.8 8 6 multiple 51633510 2013 2016 0.683 46 19.25
s60.28 MFT Sigma.DN.A 60 2.8 8 6 multiple 52453077 2013 2017 0.819 46 19.25
mz25.18 MFT M.Zuiko 25 1.8 9 7 multiple 346022424 2014 2015 0.732 46 19.25
s30.14 MFT Sigma.DN.C 30 1.4 9 7 multiple 51824954 2016 2017 0.732 52 19.25
mz30.35 MFT M.Zuiko 30 3.5 7 6 multiple ACBA37221 2016 2019 0.765 46 19.25
php26 MFT PinholePro 26 32.5 0 0 none P0348-M 2018 2018 0.567 58 19.25
solig M42 Soligor 35 3.5 5 5 single 9700253 NA 1970 1.000 46 45.46
hani SR Hanimex 35 3.5 5 5 single 13368 NA NA 0.732 46 46.00

Aproaches

Two approaches are possible for measuring spectral transmittance: a) using a spectrometer and a light source with a continuous broad emission spectrum, and b) using a thermopile as a sensor and a monochromator together a light source with a continuous broad emission spectrum.

Approach a) compares the spectrum from a light source, before and after going through an object, in our case a lens. After passing through the lens, wavelengths are “separated” in the measuring device, a spectrometer. Approach b) uses monochromatic light of many different colours (narrow wavelength ranges), produced by means of a monochromator and a light source, and a broad band sensor as measuring device. The wavelengths are separated in the light source before passing through the lens.

For a relative characterisation, it is enough to compare the shapes of the “before” and “after” spectra. For an absolute measurement, the total amount of radiation needs to be compared. Measuring the transmittance of a lens is not as straightforward as measuring the transmittance an optical filter. The lens will modify the path of the light, making it more difficult to collect all the light exiting from it.

A spectrometer is a measuring device, consisting in a monochromator and a sensor array, or a single sensor onto which light of different wavelengths are projected onto to be measured. In contrast, a light source with a broad emission spectrum followed by a monochromator that separates the different wavelengths or colours and projects them onto the object under study. Sources of high irradiance monochromatic light are very expensive devices, even more expensive than spectrometers, which are not cheap at all.

Are there any cheaper alternatives? Yes, in recent years sets of small filters have been used to assess the spectral transmittance of objectives in the UV region (see Savazzi n.d. and references therein). A board is prepared with holes covered with narrow-band-pass interference filters. Filters are illuminated from behind by means of a strong broad-band light source such as a special or modified flash or the sun and photographed through the objective to be tested. Of course one needs a camera sensitive to the wavelengths to be tested, such as a “full-spectrum” converted mirror-less or DSLR camera. This is approach b) modified by replacing the monochromator by a set of filters and the broadband sensor by the camera. For comparable results, the light source should provide a reproducible amount (irradiance) and colour (spectrum) of radiation. The advantage of this method is that a single photograph is enough to qualitatively characterise an objective.

I decided to try a different variation of approach b): to replace both the broad band light source and the monochromator by LEDs emitting at different wavelengths, using a camera as measuring device. My hope was to achieve semi-quantitative and reproducible measurements. I tested 13 objectives, each one in combination with four different filters, and without a filter. I used as a target a slab of white PTFE (“Teflon”), as this thermoplastic has very high reflectance in the range of interest, between 300 nm to 1200 nm (Depending on purity grade, thickness of the slab and cleanness of the surface up to 99% reflectance). [2018-07-16] One limitation of the approach used is that fluorescence of the glass elements of an objective cannot be distinguished from transmission. Unless the fluorescence yield is high the effect should be small, and if the yield is high it is likely to be visible to the human eye.

The present tests aim at assessing the UV transmittance of the set of fixed-focal-length (or “prime”) objectives I had available. I acquired a few of them based on the expectation of their usefulness for ultraviolet photography while others I had acquired for other uses. Although good transmittance is a requirement for successful UV photography, other properties, not tested here contribute to usability. The modern Sigma objectives from the DN Art series tested, for example perform much better than other objectives in terms of image resolution when used with a large diaphragm apertures. In practice this means, that even if of lower transmittance, they can be used at higher shutter speeds. On the other hand, objectives that have higher transmittance at shorter wavelengths, will be more suitable for false-colour processing as there will be stronger signal in the red channel, at least in sunlight. Consequently, which of these accidental objectives will be most suitable will depend on the intended use, including which filters they are paired with and what type of final rendition of the photographs is desired. The testing approach used here is only semi-quantitative, but takes into account the camera and filters used.

Methods

Equipment

For the tests I used an Olympus E-M1 (“Mk I”) camera converted to full spectrum by DSLR Astrotec. This camera is a mirror-less camera with a Micro Four-Thirds lens mount and a 16 mega pixel sensor with a crop factor of 0.5.

A Zhongyi Lens Turbo II EF-M43 adapter was tested at 365 nm with the Soligor and Nikkor lenses using M42-EF and N-EF adapters, but internal reflections made it unusable for UV.

I used four different filters: two short pass UV transmitting filters and two long pass UV-absorbing filters (Table 2). To speed-up testing I used Manfrotto’s Xume magnetic filter attachment rings.

Code
read_csv("filters.csv") %>%
  mutate(filter = factor(filter)) ->
  filters.df
kable(filters.df)
Table 2: Description of filters used for the tests.
filter make type size supplier acquired
baader Baader U-Venus 48 mm Baader planetarium 2015
edge UVROptics StraightEdgeU 52 mm UVROptics 2016
fire Firecrest UV400 52 mm Formatt Hitech 2017
haze Tiffen Haze 2A 52 mm Tiffen 2017
zwb1 Purshee ZWB1 30 mm Purshee 2018

I used four different types of narrow band LEDs, with nominal emission maxima at 405 nm, 385 nm, 365 nm and 340 nm, plus a warm white LED (Table 3). The actual position of peaks of emission differed slightly from the nominal values. The white LED was used to assess the inherent transmittance of the objectives at the f-stop setting used in the tests.

Code
read_csv("leds.csv") %>%
  mutate(led = factor(led)) ->
  leds.df
kable(leds.df)
Table 3: LEDs used for the tests. Column “led” gives the nominal emission maxima, while “wavelength” gives the measured emission maxima. “current” indicates the current setting used during testing, which for some LEDs was below the maximum rating given in the corresponding data sheet. “optical power” gives nominal values from the data sheet, but real values for individual LEDs can be expected to differ; “beam angle” values are also from the manufacturers’ data sheets.
led wavelength make current nominal power optical power beam angle type
340nm 345 nm Marktech 0.5 A 2 W 55 mW 110 MTSM340UV-F5120
365nm 368 nm LED Engin 0.7 A 3 W 1.20 W 70 LZ1-10UV00-0000
385nm 388 nm LED Engin 0.7 A 3 W 1.15 W 68 LZ1-10UB00-00U4
405nm 405 nm LED Engin 0.7 A 3 W 1.05 W 68 LZ1-10UB00-00U8
warmw 2700 K CRI 90 NICHIA 0.7 A 2.9 W 85 lm 110 NS6L183AT-H1

The partial overlap of the emission spectra of the different LEDs, gives this method much lower wavelength resolution than using a monochromator-based light source. On the other hand, using light sources and a camera allows testing the “camera + objective + filter” performance which is of interest. This is possible as camera sensors have smooth response spectra with broad peaks.

Code
photon_as_default()
four_leds.mspct <- 
  leds.mspct[c("Marktech_MTSM340UV_F5120_340nm",
               "LedEngin_LZ1_10UV00_365nm",
               "LedEngin_LZ1_10UB00_00U4_385nm",
               "LedEngin_LZ1_10UB00_00U8_405nm")]
autoplot(four_leds.mspct, 
         annotations = "peaks", 
         range = c(300,500), 
         idfactor = "LED") + 
  theme(legend.position = "none")
Warning in normalize_spct(spct = e2q(x, action = "replace.raw"), range = range,
: Normalization not updated: action not supported for objects created with
'photobiology' (<= 0.10.9).

Warning in normalize_spct(spct = e2q(x, action = "replace.raw"), range = range,
: Normalization not updated: action not supported for objects created with
'photobiology' (<= 0.10.9).

Warning in normalize_spct(spct = e2q(x, action = "replace.raw"), range = range,
: Normalization not updated: action not supported for objects created with
'photobiology' (<= 0.10.9).

Warning in normalize_spct(spct = e2q(x, action = "replace.raw"), range = range,
: Normalization not updated: action not supported for objects created with
'photobiology' (<= 0.10.9).
Figure 2: Emission spectra from the narrow-band LEDs used, normalized to the wavelength of maximum emission.
Code
autoplot(leds.mspct$Nichia_NS6L183AT_H1_sw, w.band = list(VIS()))
Figure 3: Emission spectrum from the broad-band “warm-white” LEDs used, normalized to the wavelength of maximum emission.

A slab of white “virgin” PTFE (150 mm \(\times\) 150 mm and 3 mm thick) was used as a target. It was cleaned and its surface made matt by sanding it under running water with wet/dry sandpaper (grit P2000). The target slab was illuminated for each test, with two high-power LEDs, with a broad beam (68 to 110 degrees). LEDs were firmly attached to the same tripod as the camera, so as to avoid changes in illumination. The LEDs were driven by constant current with regulation better than ±1% using a DC/DC LED driver with built-in voltage reference (RECOM RCD-24-0.70/Vref adjusted by means of a two decades precision potentiometer, Bourns 3682S-1-103L-ND). This ensured very even illumination of the target, minimal variation with time and easily repeatable settings. As a power source either a 12 V 6800 mAh Li-Po power bank or a 12 V DC 4 A power supply were used (Leicke AC Adapter NT03011).

All LEDs used where obtained ready mounted on star-boards (manufacturer’s part numbers given in Table 3). They were all individually attached onto heat sinks (Ohmite SA-LED-113E) using pre-cut double-sided heat transfer patches (t-Global Technology LP0001/01-L37-3F-0.25-2A). Each heat sink was attached with two black Nylon M5 screws to a custom-cut and bored black Nylon-6 plate. A 25 mm Arca plate was attached with a 1/4 inch (UNC) screw to the back of the nylon plate.

The camera was supported on a carbon-fibre tripod (Giotto’s MTL8361B, similar to current model YTL 8383) with a ball-head (Sirui K-20X) to which a macro focusing rail (Sunwayfoto MFR-150) was attached and then the camera attached to it (Figure 4). On the back of the focusing rail a small Arca clamp (Sunwayfoto DDC-26) was used to hold a “magic ball” (iShoot IS-MSQ) to which two 25.4 cm “magic arms” (Aputure A10) were screwed (Tarion 27 cm magic arms were used until they could be replaced by better ones). At the end of each arm a “fish-bone” Arca clamp (generic, similar to Mengs photo FC-SK25) was tightly screwed and used to hold the LED assemblies through a 25 mm Arca plate (generic, similar to Mengs PU25).

The camera shutter was triggered remotely with a wireless trigger (Hähnel Captur Receiver O/P triggered by a Captur Module-Pro remote, used manually). Using a wireless trigger not only avoided camera shake, but allowed me to trigger the camera from a distance of 1.5 to 2 m so as to avoid disturbing the illumination.

Figure 4: Camera and LEDs supported as used in objectives’ tests, before replacing the unreliable “Tarion” magic arms by the Aputure A10 arms.

Test procedure

All objectives were set at f:8.0 for the test shots in the hope of reducing possible vignetting, except for the pinhole set at f:32.5. For each shooting session, exposure was set on the PTFE slab with the Soligor 35 mm f:3.5 objective without a filter or with the Baader-U filter (session 21, where no other filter was tested), checking in-camera histograms. Exposure setting was based on the channel with strongest signal. The resulting image, was also used as reference for the calculations described below. The camera was set to manual mode and the same settings used throughout each session. Sensitivity was set to ISO 200 or ISO 320 (session 21). All images were saved as raw (.ORF) files. Paper slips with notes (Yellow Posit Notes, which fluoresce much less than white paper) were photographed to keep track of filters and adapted objectives.

The approximate photon exposure values (Table 4) are only very rough approximations based on the specifications of the LEDs, and guessing the effect of differences in radiation beam geometry.

Code
read_csv("exposure.csv") %>%
  mutate(led = factor(led)) ->
  exposure.df
kable(exposure.df)
Table 4: Approximate exposure settings used (they were varied slightly between measuring sessions to compensate for slight changes in the alignment of LEDs), and a very approximate value of relative photon exposure estimated by combining the nominal radiation output of the different LEDs from Table 3 with shutter speed needed.
led aperture shutter speed approx. photon exposure
340nm f:8.0 4 s ca. 6
365nm f:8.0 1/8-1/20 s 3.2
385nm f:8.0 1/40 s 1.6
405nm f:8.0 1/60 s 1.0
warmw f:8.0 1/30-1/40 s NA

The diaphragm aperture (f) of an objective and its light transmission (T) do not necessarily match. While f is related to the geometry of the objective, T is decreased by absorption and reflection by the glass elements and their coatings. The calibration of the f scale in objectives cannot be assumed to be correct. Consequently, the very first step was to compare visible-light T of all objectives tested.

All measurements were done in a darkened room, but the fluorescence of some objects within the room could not be completely avoided. The noise floor of the camera sensor when 1/3 to 1/10 of the image area was averaged was extremely stable and close to 0.50, even for 20 s exposure. The reason for this was the use of black level subtraction in RawDigger. The value of 0.5 was subtracted from all readings.

The readings for ambient light in the darkened room were in all sessions less than 1.0, and in most cases between 0.5 and 0.7. The full scale for E-M1 raw .ORF files is 16384 (14 bits), but highest average readings in these tests were close to 2500 and overexposure affected no pixels in the target. This gives a “space” of over 10 EV for the test.

Extraction of data from RAW images

The images were analysed with RawDigger Research Edition version 1.2.23 (https://www.rawdigger.com/). Reading the R, G1, B, and G2 counts from the image area corresponding to the PTFE target, but excluding the possibly dirty border.

Several images were taken in duplicate, and repeatability of actual readings on the same area of the target was within ±1%, except when readings were small in which case the absolute errors were between 0.1 and 0.05. Sampling different regions of the target had also little effect on counts, again within ±1%.

About 1/2 of the measurements were done twice, on separate sessions, reassembling the testing set-up in-between. This resulted in differences in absolute counts of about ±5%, but this affected equally all the objectives tested in the session, and cancelled out by the use of the Soligor objective as reference for the comparisons.

Computations

All data were analysed and plotted in R, using packages from the tidyverse and r4photobiology suites. This report was generated with R and package knitr.

The first step consisted in obtaining correction factors for relative effective T for the different objectives in visible light. These factors were later applied when comparing the relative transmittance of the objectives in the UV and violet regions of the spectrum.

The almost identical data from the two green channels were averaged as the first step of calculations. When measurements were repeated in different sessions the values were averaged after correction of the small differences between sessions. The average values read for the target area in RawDigger were entered as raw data in R.

All R chunks are embedded in the HTML output, and can be made visible by use of the “code” buttons on the right margin. The button at the very top is a master switch for the whole file and also allows to extract the source R markdown file used to generate this HTML file. If the nb.html file is opened in RStudio, the source .Rmd file will also be extracted and opened in the editor.

This is made possible by RStudio’s R Notebooks and R markdown (see https://rmarkdown.rstudio.com/r_notebooks.html).

Results

Broadband VIS radiation

Results from comparison of objectives with the target illuminated by two warm white LEDs (Figure 5). The range of variation in T-stops is 0.7 EV or a 60% variation in apparent transmittance at f:8.0.

Code
# read and prepare data

white_light.df <- read_csv("white-light-2.csv")

white_light.df %>%
  filter(!objective %in% c("z35.z", "z50.z")) %>%
  mutate(session = factor(session + 1L),
         objective = factor(objective)) %>%
  group_by(objective, session, LED) %>%
  summarise(R = mean(R) - 0.5,
            G1 = mean(G1) - 0.5,
            B = mean(B) - 0.5,
            G2 = mean(G2) - 0.5,
            n = n()) -> white_light_obj.df

white_light_obj.df %>%
  group_by(LED) %>%
  filter(objective == "solig") %>%
  select(R.ref = R,
         G1.ref = G1,
         B.ref = B,
         G2.ref = G2) %>%
  full_join(white_light_obj.df, relationship = "many-to-many") %>%
  group_by(objective, LED, session) %>%
  mutate(R.rel = R / R.ref,
         G1.rel = G1 / G1.ref,
         B.rel = B / B.ref,
         G2.rel = G2 / G2.ref,
         G.rel = (G1.rel + G2.rel) / 2,
         T.rel = (R.rel + G.rel + B.rel) / 3) ->
  white_light_T.df

white_light_T.df %>%
  group_by(objective, LED) %>%
  summarise(R.rel = mean(R.rel),
            G.rel = mean(G.rel),
            B.rel = mean(B.rel),
            T.rel = mean(T.rel)) %>%
  full_join(objectives.df, relationship = "many-to-many") %>%
  ungroup() %>%
  mutate(filter = "none",
         T.rel.corrected = T.rel * vis.factor) -> white_light_mean_T.df

white_light_mean_T.df$objective.inc.levels <-
  with(white_light_mean_T.df, reorder(objective, T.rel))

white_light_mean_T.df$objective.ordered <-
  factor(white_light_mean_T.df$objective,
         levels = c("php26", "solig", "hani", "s30.28",
                    "s60.28", "s19.28",
                    "z200", "z135", "z100", "z50", "z35", "z38", "z28", "mz25.18", "mz45.18", "dz50", "s30.14", "mz60.28", "mz30.35"))

# defaults for all transmittance plots
my_T_plots_base <-
  list(
    geom_hline(yintercept = 0, linetype = "dotted"),
    scale_y_continuous(name = "Relative T (EV)", 
                       limits = c(-11, 1), 
                       breaks = c(-10, -8,-6,-4,-2,0,2)),
    scale_x_discrete(name = "Objectives"),
    facet_grid(LED~filter), # , labeller = label_both
    theme_bw(),
    theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))
  )
camera_subtitle <- "f:8, Olympus E-M1, converted to 'full spectrum' by DSLR Astrotec"
Code
ggplot(white_light_mean_T.df,
       aes(objective.inc.levels, log2(T.rel), fill = coating,
           size = elements)) +
  geom_hline(yintercept = 0, linetype = "dotted") +
  stat_summary(geom = "point", fun = mean, na.rm = TRUE, shape = 21) +
  scale_y_continuous(name = "Relative T (EV)") +
  scale_x_discrete(name = "Objectives") +
  scale_size(limits = c(0,14), breaks = c(0,5,7,9,11,13)) +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)) +
  ggtitle("RGB average", paste("Warm white LEDs", camera_subtitle, sep = ", "))
Figure 5: Transmittance of the tested objectives to white light. Colour of the symbols indicates type of AR coating and size of the symbols, the number optical elements. The horizontal dotted line highlights the objective used as reference in all tests.

For comparison with the plots in the next section, we plot the same data as above, but using the same scale range and format as in the plots in the next section for the narrow-band LEDs (Figure 6).

Code
fig.top <-
  ggplot(subset(white_light_mean_T.df, !is.na(LED)),
         aes(objective.inc.levels, log2(T.rel))) +
  geom_col(fill = "white", colour = "black", width = 2/3) +
  my_T_plots_base +
  ggtitle("RGB average, before correction", paste("Warm white LEDs", camera_subtitle, sep = ", "))

fig.bottom <-
  ggplot(subset(white_light_mean_T.df, !is.na(LED)),
       aes(objective.inc.levels, log2(T.rel.corrected))) +
  geom_col(fill = "white", colour = "black", width = 2/3) +
  my_T_plots_base +
  ggtitle("RGB average, after correction", paste("Warm white LEDs", camera_subtitle, sep = ", "))

fig.top / fig.bottom
Figure 6: Transmittance of the tested objectives to white light, estimated from the mean signal of the R, G and B channels. The horizontal line highlights the objective used as reference. The range is 0.7 EV or a 60% variation in apparent transmittance. This is shown in the top panel. In the lower panel the same correction (based on the R channel) as applied to all subsequent plots to compensate for the objective transmittance and possible miss-calibration of the aperture scale is also applied to the visible light measurement.

Narrow band UVA radiation and violet light

In this section we present results for LEDs with nominal emission maxima at 340 nm, 365 nm, 385 nm, and 405 nm.

Code
# read data

uva_rad.df <- read_csv("uv-radiation.csv")

uva_rad.df %>%
  mutate(session = factor(session + 1L),
         objective = factor(objective)) %>%
  filter(!objective %in% c("z35.z", "z50.z")) %>%
  group_by(objective, LED, filter, session) %>%
  summarise(R = mean(R, na.rm = TRUE) - 0.5,
            G1 = mean(G1, na.rm = TRUE) - 0.5,
            B = mean(B, na.rm = TRUE) - 0.5,
            G2 = mean(G2, na.rm = TRUE) - 0.5,
            n = n()) %>%
  ungroup() -> uva_rad.df

uva_rad.df %>%
  group_by(LED, session) %>%
  filter(objective == "solig", filter == "baader") %>%
  select(LED,
         session,
         R.ref = R,
         G1.ref = G1,
         B.ref = B,
         G2.ref = G2,
         -filter) %>%
  full_join(uva_rad.df) %>%
  group_by(objective, LED, filter, session) %>%
  mutate(R.rel = R / R.ref,
         G1.rel = G1 / G1.ref,
         B.rel = B / B.ref,
         G2.rel = G2 / G2.ref,
         G.rel = (G1.rel + G2.rel) / 2,
         T.rel = (R.rel + G.rel + B.rel) / 3) %>%
  ungroup() -> uva_rad_T.df

uva_rad_T.df %>%
  group_by(objective, LED, filter) %>%
  summarise(R.rel = mean(R.rel, na.rm = TRUE),
            G.rel = mean(G.rel, na.rm = TRUE),
            B.rel = mean(B.rel, na.rm = TRUE),
            T.rel = mean(T.rel, na.rm = TRUE)) %>%
  full_join(objectives.df, by = "objective") %>%
  ungroup() %>%
  mutate(R.rel.corrected = R.rel * vis.factor,
         G.rel.corrected = G.rel * vis.factor,
         B.rel.corrected = B.rel * vis.factor,
         T.rel.corrected = T.rel * vis.factor) -> uva_rad_mean_T.df

uva_rad_mean_T.df$objective.ordered <-
  factor(uva_rad_mean_T.df$objective,
         levels = c("php26", "solig", "hani", "s30.28", "z35", "nk24.28",
                     "s19.28", "z100", "s60.28", "mz30.35",  "z28",
                    "z200", "z50", "z38", 
                    "mz25.18", "mz45.18", "dz50", "z135", "s30.14", "mz60.28"))
uva_rad_mean_T.df$filter <-
  factor(uva_rad_mean_T.df$filter,
         levels = c("baader", "edge", "none", "fire", "haze", "zwb1"),
         labels = c("Baader U", "StraightEdgeU", 
                    "no filter",
                    "UV400", "Haze 2A", "ZWB1"))
uva_rad_mean_T.df$LED <- factor(uva_rad_mean_T.df$LED)

uva_rad_mean_T.df <-
  filter(uva_rad_mean_T.df, !is.na(filter) & !is.na(LED))

The central column shows results for measurements without a filter. Thee describe the sum of UV and VIS radiation reaching the camera sensor. In the case of illumination at 405 nm, most of the radiation is visible. However, in the case of illumination with shorter wavelength, it excited some fluorescence from objects in the room. Even fluorescence within the objective itself is possible, which would reach the sensor also in the case of the the UV-pass filters. The two columns on the right, correspond to UV blocking filters. These should give some idea of the amount of “contamination”” by fluorescence.

We consider first the violet 405 nm LED. This provides VIS radiation, with a small overlap with UVA. Differences among objectives are small, while differences among filters are clear. The UV400 filter can be expected to transmit 50% at 400 nm. In addition it is a multi-coated filter and as could be expected causes only very slight attenuation. The Haze 2A filter according to specifications absorbs some violet and blue visible light, and this is clearly reflected in the plot. In addition this filter is not coated. At about -2 EV, it transmits close to 1/4 of the light. On the left side of the plot, we see that the Baader U filter attenuates by between 6 and 7 EV, or transmits less than 2%. The StraightedEdgeU filter has a very steep slope starting at 400 nm, reaching high transmittance at longer wavelengths than the Baader-U, consequently transmitting some long UVA, and consequently transmitting some of the radiation emitted by the violet LED. In numbers, it attenuates by about 5 EV, or transmitting approximately 3%.

The spectrum of the LED with peak emission at 387 nm (long UVA) has a tail that reaches rather far into the VIS region. However, with this LED already we can detect major differences among objectives. The EV scale is a log\(_2\) based scale. We see a clear difference between the two UV-blocking filters, although they both transmit a relatively small fraction of the radiation measured without a filter: -3.5 EV or about 10% for the UV400 filter and -5.2 EV or about 2.7% for the Haze 2A. With this LED, differences among objectives are also revealed. One should not read the change in transmittance across columns corresponding to different filters as reflecting the properties of objectives, as the filters do not themselves transmit all the radiation. Comparison are only valid between objectives within a given column of panels. About half of the objectives perform well. Four or five of them seem to be as good as the Soligor, which we have used as reference for UV-transmission. The StraightEdgeU filter has almost 1 EV of advantage over the Baader-U with this LED.

The spectrum of the LED with peak of emission at 368 nm has a tail that barely goes past 400 nm. There is only the slightest difference between the two UV blocking filters, and the Baader-U in the case performs slightly better than the StraightEdgeU filter. The differences among objectives, are now clearer, with the Sigma 30 mm f:2.8 transmitting almost as much as the Soligor 35 mm, and the G.Zuiko 30 mm f:2.8, following close behind. Next is the Sigma 19 mm f:2.8, transmitting about 1/2 of what the Soligor transmits. The G.Zuiko 28 mm f:3.5, shows very little difference in transmittance compared to the Sigma 19 mm. The Baader-U filter, transmitting proportionally less of the longer wavelengths within the UV region, better discriminates between the different objectives.

The spectrum of the LED with peak of emission at 345 nm is rather narrow, but asymmetrical, with a longer tail towards longer wavelengths. Clearly only the Soligor 35 mm performs well with this LED. Second in transmittance is the G.Zuiko 35 mm f:2.8, but at over -3 EV it is far behind the Soligor. The Sigma 30 mm f:2.8 is only slightly behind the G.Zuiko 35 mm.

Code
uva_rad_mean_T.df %>%
  ggplot(aes(objective.ordered, log2(T.rel.corrected))) +
  geom_col(fill = "grey50", alpha = 0.5, colour = "black", width = 2/3) +
  my_T_plots_base +
  ggtitle("RGB average", paste("UVA LEDs", camera_subtitle, sep = ", ")) +
  coord_flip()
Figure 7: Transmittance of the tested objectives to UVA radiation and violet light. The horizontal line highlights the objective used as reference. This figure presents the average relative transmittance when the responses of the three colour channels of the camera sensor are averaged.

When comparing the different colour channels of the camera sensor, we see that the biggest differences can be seen in the red channel. It can be expected that the red channel records the shorter wavelength part of the UVA region and the blue channel the longest wavelength region within the UVA. It should be kept in mind that the data in the next three figures have been normalized separately for each channel using the Soligor 35 mm objective as reference.

Code
ggplot(uva_rad_mean_T.df,
       aes(objective.ordered, log2(R.rel.corrected))) +
  geom_col(fill = "red", alpha = 0.5, colour = "black", width = 2/3) +
  my_T_plots_base +
  ggtitle("Red channel", paste("UVA LEDs", camera_subtitle, sep = ", ")) +
  coord_flip()
Figure 8: Transmittance of the tested objectives to UVA radiation and violet light. The horizontal line highlights the objective used as reference. This figure presents the relative transmittance computed based on the response of the red-sensitive channel of the camera sensor.
Code
ggplot(uva_rad_mean_T.df,
       aes(objective.ordered, log2(G.rel.corrected))) +
  geom_col(fill = "darkgreen", alpha = 0.5, colour = "black", width = 2/3) +
  my_T_plots_base +
  ggtitle("Green channel", paste("UVA LEDs", camera_subtitle, sep = ", ")) +
  coord_flip()
Figure 9: Transmittance of the tested objectives to UVA radiation and violet light. The horizontal line highlights the objective used as reference. This figure presents the relative transmittance computed based on the response of the green-sensitive channel of the camera sensor.
Code
ggplot(uva_rad_mean_T.df,
       aes(objective.ordered, log2(B.rel.corrected))) +
  geom_col(fill = "blue", alpha = 0.5, colour = "black", width = 2/3) +
  my_T_plots_base +
  ggtitle("Blue channel", paste("UVA LEDs", camera_subtitle, sep = ", ")) +
  coord_flip()
Figure 10: Transmittance of the tested objectives to UVA radiation and violet light. The horizontal line highlights the objective used as reference. This figure presents the relative transmittance computed based on the response of the blue-sensitive channel of the camera sensor.
Code
uva_rad.df %>%
  mutate(G = (G1 + G2) / 2) %>%
  group_by(objective, LED, filter) %>%
  summarise(R = mean(R, na.rm = TRUE),
            G = mean(G, na.rm = TRUE),
            B = mean(B, na.rm = TRUE)) %>%
  ungroup() %>%
  transmute(LED = LED,
            filter = filter,
            objective = objective,
            objective.filter = paste(objective, filter, sep = "."),
            RGB = R + G + B,
            R = R / RGB,
            G = G / RGB,
            B = B / RGB,
            objective.ordered = reorder(objective, -R)) %>%
  filter(LED == "340nm", filter %in% c("baader", "edge", "zwb1")) %>%
  arrange(LED, filter) -> channel_test_objectives.df

gather(channel_test_objectives.df,
       key = "sensor.channel",
       value = "response.fraction",
       R, G, B,
       factor_key = TRUE) -> channel_test_objectives_tidy.df

channel_plots_base <-
  list(
    scale_y_continuous(name = "Relative response (%)", breaks = c(0, 33.3, 66.7, 100)),
    scale_x_discrete(name = "objective"),
    scale_fill_manual(name = "sensor\nchannel", values = c(R = "red", G = "darkgreen", B = "blue")),
    facet_wrap(~filter, labeller = label_both),
    theme_bw(),
    theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)),
    ggtitle("Olympus E-M1, converted to 'full-spectrum' by DSLR Astrotec",
            "Objectives at f:8.0, 340 nm LED")
  )
Code
ggplot(channel_test_objectives_tidy.df,
       aes(objective.ordered, response.fraction * 100, fill = sensor.channel)) +
  geom_col(colour = "black", alpha = 0.5, width = 1) +
  channel_plots_base  +
  coord_flip()
Figure 11: Relative response of sensor channels for the different objectives with the PTFE target illuminated by 340nm LED, and the Baader-U filter or the StraightEdgeU filter on the objective.
Code
# prepare channel data

uva_rad.df %>%
  mutate(G = (G1 + G2) / 2) %>%
  group_by(objective, LED, filter) %>%
  summarise(R = mean(R, na.rm = TRUE),
            G = mean(G, na.rm = TRUE),
            B = mean(B, na.rm = TRUE)) %>%
  ungroup() %>%
  transmute(LED = LED,
            filter = filter,
            objective = objective,
            objective.filter = paste(objective, filter, sep = "."),
            RGB = R + G + B,
            R = R / RGB,
            G = G / RGB,
            B = B / RGB,
            objective.ordered = reorder(objective, -R)) %>%
  filter(LED == "365nm", filter %in% c("baader", "edge", "zwb1")) %>%
  arrange(LED, filter) -> channel_test_objectives.df

gather(channel_test_objectives.df,
       key = "sensor.channel",
       value = "response.fraction",
       R, G, B,
       factor_key = TRUE) -> channel_test_objectives_tidy.df

# defaults for channel response plots

channel_plots_base <-
  list(
    scale_y_continuous(name = "Relative response (%)", breaks = c(0, 33.3, 66.7, 100)),
    scale_x_discrete(name = "objective"),
    scale_fill_manual(name = "sensor\nchannel", values = c(R = "red", G = "darkgreen", B = "blue")),
    facet_wrap(~filter, labeller = label_both),
    theme_bw(),
    theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)),
    ggtitle("Olympus E-M1, converted to 'full-spectrum' by DSLR Astrotec",
            "Objectives at f:8.0, 365 nm LED")
  )
Code
ggplot(channel_test_objectives_tidy.df,
       aes(objective.ordered, response.fraction * 100, fill = sensor.channel)) +
  geom_col(colour = "black", alpha = 0.5, width = 1) +
  channel_plots_base +
  coord_flip()
Figure 12: Relative response of sensor channels for the different objectives with the PTFE target illuminated by 365nm LED, and the Baader-U filter or the StraightEdgeU filter on the objective.
Code
uva_rad.df %>%
  mutate(G = (G1 + G2) / 2) %>%
  group_by(objective, LED, filter) %>%
  summarise(R = mean(R, na.rm = TRUE),
            G = mean(G, na.rm = TRUE),
            B = mean(B, na.rm = TRUE)) %>%
  ungroup() %>%
  transmute(LED = LED,
            filter = filter,
            objective = objective,
            objective.filter = paste(objective, filter, sep = "."),
            RGB = R + G + B,
            R = R / RGB,
            G = G / RGB,
            B = B / RGB,
            objective.ordered = reorder(objective, -R)) %>%
  filter(LED == "385nm", filter %in% c("baader", "edge", "zwb1")) %>%
  arrange(LED, filter) -> channel_test_objectives.df

gather(channel_test_objectives.df,
       key = "sensor.channel",
       value = "response.fraction",
       R, G, B,
       factor_key = TRUE) -> channel_test_objectives_tidy.df

channel_plots_base <-
  list(
    scale_y_continuous(name = "Relative response (%)", breaks = c(0, 33.3, 66.7, 100)),
    scale_x_discrete(name = "objective"),
    scale_fill_manual(name = "sensor\nchannel", values = c(R = "red", G = "darkgreen", B = "blue")),
    facet_wrap(~filter, labeller = label_both),
    theme_bw(),
    theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)),
    ggtitle("Olympus E-M1, converted to 'full-spectrum' by DSLR Astrotec",
            "Objectives at f:8.0, 385 nm LED")
  )
Code
ggplot(channel_test_objectives_tidy.df,
       aes(objective.ordered, response.fraction * 100, fill = sensor.channel)) +
  geom_col(colour = "black", alpha = 0.5, width = 1) +
  channel_plots_base +
  coord_flip()
Figure 13: Relative response of sensor channels for the different objectives with the PTFE target illuminated by 385nm LED, and the Baader-U filter or the StraightEdgeU filter on the objective.

Photographs in UVA

Sigma 30 mm f:2.8 DN in the field

An informal test of the Sigma 30 mm f:2.8 DN A objective in actual use. The resolution of the close-up photograph is hindered by the need to use high ISO and hand-holding the camera while using a shutter speed of 1/10 s. Still strong false colour is achieved easily and quite good resolution even with the diaphragm fully open. For close-ups a tripod would be of limited help as blur is mostly caused by flowers moving in the wind.

Figure 14: Photograph taken with the Sigma 30 mm f:2.8 DN, MFT objective; Baader U-filter; partial shade on a sunny afternoon. Handheld, autofocus, auto-exposure. White balanced and edited in PhotoNinja. Settings: ISO 3200, f:2.8, 1/10 s. Marsh Marigold, Caltha palustris at Lake Bled, Slovenia, 13 April 2018. Half shade.

The broader view bellow, at a location some meters away from the photo above, at lower ISO renders a much sharper image. The yellow false colour of the C. palustris is intense and the false blue of the Viola flowers and lichen on the trunk can be also seen. Some of the flowers did move in the breeze as well as the lake water.

Figure 15: Photograph taken with the Sigma 30 mm f:2.8 DN, MFT objective; UVROptics StraightEdgeU filter; partial shade on a sunny afternoon. Handheld, autofocus, auto-exposure. White balanced and edited in PhotoNinja. Settings: ISO 1600, f:2.8, 1/10 s. Marsh Marigold, Caltha palustris on the shore of Lake Bled, Slovenia, 13 April 2018. Half shade. Water is visible on the lower right corner.

When focused at infinity the resolution obtained with the Sigma 30 mm f:2.8 DN A objective is very good at f:2.8, and improves slightly at f:4.0. On a sunny spring day this allows the use of low ISO together with relatively fast shutter speed. This makes handheld UVA landscape photography very simple, relying on auto-exposure and auto focus.

Figure 16: Photograph of Bled, Slovenia, across the lake taken with the Sigma 30 mm f:2.8 DN, MFT objective; UVROptics StrightEdgeU filter; broken cloud cover on a sunny afternoon. Handheld, autofocus, auto-exposure. White balanced and edited in PhotoNinja. Settings: ISO 250, f:4.0, 1/30 s. 13 April 2018.

A comparison photograph in NIR shows the expected reduction of haze and increased contrast in distant subjects with what looks like slightly better resolution than in the UVA photograph above. The photographs were taken with the same camera settings only swapping the filters (automatically resulting in a higher shutter speed) only 2 min apart.

Figure 17: Photograph of Bled across the lake taken with the Sigma 30 mm f:2.8 DN, MFT objective; Heliopan (Schott glass) RG780 filter; broken cloud cover on a sunny afternoon. Handheld, autofocus, auto-exposure. White balanced and edited in PhotoNinja. Settings: ISO 250, f:4.0, 1/640 s. 13 April 2018.

Sigma 60 mm f:2.8 DN in the field

Although according to the tests described above, UV transmittance of the 60 mm objective is somehow lower than that of the 30 mm objective in the same series from Sigma, in real world use in the field with the UVROptics StraightEdgeU filter, any difference in exposure is masked by the differences in angle of view and minor variation in illumination. In contrast when using the Baader U filter the resulting images have an unusual yellow colour cast. I have yet to workout what was the cause of this colour cast.

Discussion

I consider that the approach used for testing works satisfactorily. It is rather laborious, but not overly, and the necessary equipment and set-up are rather cheap, at least if one has additional uses for the equipment. Compared to direct transmittance measurement it does not allow the characterization of objectives on their own, but instead of the camera plus objective, and filters. Depending on the case, this can be seen as a disadvantage or as an advantage.

With respect to the old objectives, there were no big surprises. The Soligor 35 mm is a very close relative, if not identical, to the “accidental” UV objective considered to be best by many. The G.Zuiko 35 mm f:2.8, is listed at (http://www.ultravioletphotography.com) as UV capable and reaching 340 nm while the Soligor could be expected to reach 325 nm. Giving a single wavelength as a limit, requires the transmittance threshold to be specified. Even if the G.Zuiko 35 mm f:2.8 seems to perform badly at 340 nm in the current tests, it still transmits about 12% of what the Soligor transmits, so at -3 EV it is near the threshold used in the previous test by Klauss Schmitt (http://photographyoftheinvisibleworld.blogspot.fi/2010/01/study-of-50-lenses-for-uv-photography.html). So, no conflict with earlier tests. The G.Zuiko 28 mm f:3.5, seems to be a new find, but this is not surprising as it is similar in design to the G.Zuiko 35 mm f:2.8.

Sigma Art 19 mm and 30 mm f:2.8 DN A objectives have been mentioned as usable in UV, especially the 19 mm f:2-8 DN A. This objective is indeed quite usable, but not exceptional. I haven’t seen any earlier formal test of the 30 mm objective in the same series. It is surprisingly good, not matching the Soligor at 345 nm, but matching or surpassing it at 368 nm and 387 nm. This is quite a feat for a design that is only five years old. If one takes into account the design of this objective, then the good performance has a justification: it is an objective of simple construction with 7 elements in 5 groups, while the G.Zuiko 35 mm with comparable performance has 7 elements in 6 groups. The better performing Soligor, has 5 elements in 5 groups. I expected the E.Zuiko 100 mm f:2.8 to perform well as it has also 5 elements in 5 groups, but this was only partly true. The low UVA transmittance of the M.Zuiko 25 mm f:1.8, is a counter-example, being also a recent design with a simple optical design.

The tests described above are based on a plain slab of white PTFE. If a suitable non-fluorescing target with a resolution test pattern would be found or made, the objectives could be semi-quantitatively tested for image resolution in the UV at different f-stops. If the amount of radiation reflected by the slab when illuminated by the different LEDs would be quantified, then the relative sensitivity of the whole camera plus objective and filter system could be assessed. The reflected radiation quantification needs only to be relative across LEDs of different types, and expressed as photons (a real estimate to replace my rough guesses shown in Table 4). As time allows, I will work on some of these further developments. I also plan to add as a second reference an UV-Nikkor 105 mm. I am also curious about the performance of an off-the-shelf E-M1 camera compared to the full-spectrum converted one.

I have bought three “special” objectives, which I expect to receive in coming weeks: two “Thingyfy” Pinhole Pro objectives (PPS11 at 11 mm and Pro mirrorless at 26 mm) and an old Olympus OM 38 mm f:3.5 macro (optimized ×1.8 – ×6.0 magnification, low serial number, with single anti reflection coating, five elements in four groups, see http://www.alanwood.net/photography/olympus/macro-lens-38-35.html).

Equipment suppliers

Formatt Hitech: (https://www.formatt-hitech.com/) Baader Planetarium: (http://www.baader-planetarium.com/en/) Tiffen: (https://tiffen.com/tiffen-filters/) UVR Optics: (http://www.uvroptics.com) Sunwayfoto: (http://www.sunwayfoto.com/e_index.aspx) iShoot: (http://www.photoloving.com/) Aputure: (https://www.aputure.com/) Sirui: (http://www.sirui.eu/en/) Giottos: (http://www.giottos.com/) Mengs: (https://www.mengsphoto.com/) LED Engin: (http://www.ledengin.com/) Marktech: (http://www.marktechopto.com/) Nichia: (http://www.nichia.co.jp/en/) RECOM: (https://www.recom-power.com/) Ohmite: (http://www.ohmite.com) Bourns: (http://www.bourns.com/) Olympus: (https://www.olympus-europa.com/site/en/c/cameras/) Sigma: (https://www.sigmaphoto.com/) Thingyfy: (http://thingyfy.com/story-lens/) DSLR Astro TEC: (http://www.dslr-astrotec.de/index-eng.html) GFG Plastics: (http://gfgplastics.uk/)

Electronic components were sourced from distributors: Digi-key electronics: (https://www.digikey.com/en/) Mouser electronics: (https://eu.mouser.com/) Farnell: (http://www.farnell.com/) LUMITRONIX LED Technik GmbH: (https://www.leds.de)

Tip

The figures were produced in R with R package ‘ggspectra’, which is an extension to package ‘ggplot2’. All these packages are open-source and available through CRAN. See also the R for photobiology web site.

The code is included in this page, but “folded”. To display the code used to produce the figures click on the word Code or the triangle next to it. The data can be found in the GitHub repository for these web site. There is a link to the repository in the ABOUT menu at the top of the page.