Set this flag to TRUE when you want to write out plots.
write.plot.enabled = F
library(data.table)
library(dplyr)
library(ggplot2)
library(jsonlite)
Read Meade 4000 filter set data from files
filter <- data.frame(wavelength=c(), transmission=c(), name=c())
for (name in filter.names) {
filename <- paste0("Meade 4000 Filter ",name,".csv")
filter <- rbind(filter, preprocess.filter(read.filter(filename), seq(200,900), name))
}
Plot transmission of Meade 4000 filter set
p <- ggplot(data=filter) +
geom_line(aes(wavelength,transmission,color=factor(name, levels=c(filter.names, "None")))) +
scale_colour_manual(name="Filter", values=filter.colors, labels=filter.labels) +
labs(title="Meade 4000 Filter", x="Wavelength [nm]", y="Transmission [%]") +
theme_bw() +
coord_cartesian(xlim=c(250,800))
p
if (write.plot.enabled) write.plot(p, "Transmission")
Read data for scotopic and photopic vision from file
vision <- rbind(read.vision("scvle.csv", "Scotopic"), read.vision("vljve.csv", "Photopic"))
vision$type = factor(vision$type, levels=c("Scotopic", "Photopic")) # Reorder vision type
Wavelength limits for plots
w.min <- max(min(vision$wavelength), 380)
w.max <- min(max(vision$wavelength), 720)
Plot relative luminous efficency of photopic and scotopic vision
p <- ggplot(data=vision) +
geom_line(aes(wavelength,rle,color=type)) +
scale_color_manual(name="Vision", values=c("black","grey70")) +
labs(title="Vision Efficiency", x="Wavelength [nm]", y="Relative Luminous Efficiency") +
coord_cartesian(xlim=c(w.min,w.max)) +
theme_bw()
p
if (write.plot.enabled) write.plot(p)
Read solar spectral distribution from file
sun <- read.csv("ASTMG173.csv", header=F, skip=2)[,c(1,3)]
colnames(sun) <- c("wavelength","irradiance")
Set the average solar irradiance between 630 and 690 nm to one
N <- mean(sun$irradiance[which(sun$wavelength == 630):which(sun$wavelength == 690)])
sun$irradiance <- sun$irradiance / N
Plot solar spectral distribution
p <- ggplot(data=sun) +
geom_line(aes(wavelength,irradiance)) +
labs(title="Solar Spectral Irradiance / Air Mass 1.5", x="Wavelength [nm]", y="Irradiance") +
theme_bw() +
coord_cartesian(xlim=c(w.min,w.max))
p
Calculate flux for visual observing of sunlit object under scotopic and photopic conditions
sunlit.data <- rbind(
make.sunlit.data(filter, vision, "Scotopic", sun),
make.sunlit.data(filter, vision, "Photopic", sun)
)
sunlit.flux <- sunlit.data %>%
# Reorder vision.
mutate(vision = factor(vision, levels=c("Scotopic","Photopic"))) %>%
# Group by vision and filter.
group_by(vision, filter) %>%
# Add vision specific constant.
mutate(k = ifelse(vision == "Scotopic", 1699, 683)) %>%
# Calculate flux.
summarize(flux = sum(fle * irradiance * reflectance * k)) %>%
# Sort by flux.
arrange(-flux)
print(data.table(sunlit.flux))
## vision filter flux
## 1: Scotopic None 180828.5546
## 2: Scotopic 82A 163391.6940
## 3: Scotopic 8 152820.0533
## 4: Scotopic 80A 104859.6375
## 5: Scotopic 11 104451.7505
## 6: Scotopic 56 62305.8152
## 7: Scotopic 58 45900.9903
## 8: Scotopic 38A 23159.3168
## 9: Scotopic 21 8272.4053
## 10: Scotopic 47 5343.3646
## 11: Scotopic 23A 2684.8845
## 12: Scotopic 25A 795.5685
## 13: Photopic None 79609.2418
## 14: Photopic 8 73531.9428
## 15: Photopic 82A 68834.3033
## 16: Photopic 11 58546.4630
## 17: Photopic 21 31978.4646
## 18: Photopic 80A 30406.1984
## 19: Photopic 56 28906.3474
## 20: Photopic 23A 20450.6883
## 21: Photopic 58 17103.7880
## 22: Photopic 25A 12034.1782
## 23: Photopic 38A 1524.4048
## 24: Photopic 47 301.1459
## vision filter flux
Plot flux for visual observing of a sunlit object
p <- ggplot(sunlit.flux) +
geom_bar(aes(x=filter,y=flux,fill=factor(filter, levels=c(filter.names, "None"))),stat="identity") +
scale_fill_manual(name="Filter", values=filter.colors, labels=filter.labels) +
facet_grid(. ~ vision) +
labs(title="Sunlit Object", x="Wavelength [nm]", y="Flux [p.d.u.]") +
theme_bw()
p
if (write.plot.enabled) write.plot(p)
Read Jupiter NEB/NTrZ reflectance data from file
neb <- read.csv("NEB.csv")
ntrz <- read.csv("NTrZ.csv")
Plot of Jupiter NEB/NTrZ reflectance
p <- ggplot(data=rbind(neb,ntrz)) +
geom_line(aes(wavelength, reflectance, color=feature)) +
scale_color_discrete(name="Feature") +
labs(title="Jupiter Reflectance", x="Wavelength [nm]", y="Reflectance [p.d.u.]") +
theme_bw() +
coord_cartesian(xlim=c(w.min,w.max))
p
if (write.plot.enabled) write.plot(p)
Calculate flux and contrast for visual observing Jupiter under scotopic and photopic conditions
jupiter.data <- rbind(
make.jupiter.data(filter, vision, "Scotopic", neb, ntrz),
make.jupiter.data(filter, vision, "Photopic", neb, ntrz)
)
jupiter.flux <- jupiter.data %>%
# Adjust vision order.
mutate(vision=factor(vision, levels=c("Scotopic","Photopic"))) %>%
# Add vision specific constant.
mutate(k = ifelse(vision=="Scotopic",1699,683)) %>%
# Group by vision and filter.
group_by(vision, filter) %>%
# Calculate flux.
summarize(flux.neb=sum(k*fle*neb), flux.ntrz=sum(k*fle*ntrz)) %>%
# Calculate Michelson contrast.
mutate(michelson=(flux.ntrz-flux.neb)/(flux.ntrz+flux.neb)) %>%
# Calculate Weber contrast.
mutate(weber=(flux.ntrz-flux.neb)/(flux.ntrz)) %>%
# Sort by contrast.
arrange(-michelson)
print(data.table(jupiter.flux))
## vision filter flux.neb flux.ntrz michelson weber
## 1: Scotopic 47 4814.8283 6332.0067 0.13610845 0.23960467
## 2: Scotopic 38A 17855.1740 23450.3667 0.13545865 0.23859724
## 3: Scotopic 80A 80226.5267 101919.6436 0.11909730 0.21284530
## 4: Scotopic 82A 125118.8880 156832.6806 0.11247957 0.20221418
## 5: Scotopic None 138643.9680 173499.9945 0.11166651 0.20089929
## 6: Scotopic 8 115699.2222 143990.6788 0.10894323 0.19648117
## 7: Scotopic 58 34817.7088 42982.7677 0.10494870 0.18996122
## 8: Scotopic 11 79757.4754 97906.3743 0.10215302 0.18536994
## 9: Scotopic 56 47548.7074 58356.4484 0.10205113 0.18520217
## 10: Scotopic 21 7000.1660 7713.6329 0.04848964 0.09249427
## 11: Scotopic 23A 2356.7722 2534.4421 0.03632430 0.07010218
## 12: Scotopic 25A 722.4019 763.5347 0.02768135 0.05387146
## 13: Photopic 47 286.4265 371.8131 0.12971971 0.22964938
## 14: Photopic 38A 1175.9206 1523.1293 0.12864106 0.22795744
## 15: Photopic 58 13424.7239 15935.4852 0.08551579 0.15755789
## 16: Photopic 56 23106.5216 26939.2607 0.07658466 0.14227336
## 17: Photopic 80A 24616.6349 28679.8316 0.07623764 0.14167436
## 18: Photopic 82A 56606.6272 64794.3680 0.06744377 0.12636501
## 19: Photopic None 65622.7091 74958.6850 0.06640976 0.12454829
## 20: Photopic 11 48036.3705 54831.0920 0.06605316 0.12392096
## 21: Photopic 8 60616.4020 69057.0836 0.06509181 0.12222760
## 22: Photopic 21 28280.5154 30351.8320 0.03532720 0.06824355
## 23: Photopic 23A 18583.9462 19636.1271 0.02752954 0.05358393
## 24: Photopic 25A 11211.1833 11699.2875 0.02130485 0.04172085
## vision filter flux.neb flux.ntrz michelson weber
Plot contrast for visual observing Jupiter
p <- ggplot(jupiter.flux) +
geom_bar(aes(x=filter,y=michelson,fill=factor(filter, levels=c(filter.names, "None"))),stat="identity") +
scale_fill_manual(name="Filter", values=filter.colors, labels=filter.labels) +
facet_grid(. ~ vision) +
labs(title="Jupiter", x="Wavelength [nm]", y="Contrast") +
theme_bw()
p
if (write.plot.enabled) write.plot(p)
Smart approx function
approx.y <- function(x, y = NULL, xout, rule=2, ...) {
approx(x,y=y,xout=xout,rule=rule,...)$y
}
Filter names
filter.names <- c(
"8" , "11" , "21", "23A", "25A", "38A", "47" , "56" , "58", "80A", "82A"
)
Filter colors
filter.colors <- c(
"yellow", "yellowgreen", "orange", "red", "red3", "blue", "purple", "green", "green3", "deepskyblue3",
"skyblue", "black"
)
Filter labels
filter.labels <- c(
"#8", "#11", "#21", "#23A", "#25A", "#38A", "#47", "#56", "#58", "#80A", "#82A", "None"
)
Function to set up data frame for visual observing Jupiter
make.jupiter.data <- function(filter, vision, vision.type, neb, ntrz) {
subvision <- subset(vision, type==vision.type)
wavelength <- seq(min(filter$wavelength), max(filter$wavelength))
# Create data frame with wavelength, transmission, filter.
df <- data.frame(wavelength = filter$wavelength, transmission = filter$transmission, filter = filter$name)
# Add plain vision data.
df <- rbind(df, data.frame(wavelength = wavelength, transmission = 100, filter = "None"))
# Add relative luminous efficiency.
df$rle <- approx.y(subvision$wavelength, subvision$rle, df$wavelength)
# Add filtered luminous efficiency.
df$fle <- df$rle * df$transmission / 100
# Add Jupiter NEB reflectance.
df$neb <- approx.y(neb$wavelength, neb$reflectance, df$wavelength)
# Add Jupiter NTrZ reflectance.
df$ntrz <- approx.y(ntrz$wavelength, ntrz$reflectance, df$wavelength)
# Add vision.
df$vision <- vision.type
df
}
Function to set up data frame for visual observing of a sunlight object
make.sunlit.data <- function(filter, vision, vision.type, sun, reflectance=1) {
subvision <- subset(vision, type==vision.type)
wavelength <- seq(min(filter$wavelength), max(filter$wavelength))
# Create data frame with wavelength, transmission, filter.
df <- data.frame(wavelength = filter$wavelength, transmission = filter$transmission, filter = filter$name)
# Add plain vision data.
df <- rbind(df, data.frame(wavelength = wavelength, transmission = 100, filter = "None"))
# Add relative luminous efficiency.
df$rle <- approx.y(subvision$wavelength, subvision$rle, df$wavelength)
# Add filtered luminous efficiency
df$fle <- df$rle * df$transmission/100
# Add solar spectral irrandiance
df$irradiance <- approx.y(sun$wavelength, sun$irradiance, df$wavelength)
# Add reflectance for a spectral uniform reflector.
df$reflectance <- reflectance
# Add vision.
df$vision <- vision.type
# Return.
df
}
Function to preprocess filter data
preprocess.filter <- function(df, wavelength, name) {
data.frame(
wavelength = wavelength,
transmission = approx.y(df$wavelength, df$transmission, wavelength),
name=name
)
}
Function to read in filter data
read.filter <- function(name) {
read.csv(name, col.names=c("wavelength","transmission","X"))[,1:2]
}
Function to read vision data from file
read.vision <- function(filename, type) {
df <- read.csv(filename)
df$type <- type
df
}
Function used to write plot to PNG file
write.plot <- function(p, name=NULL, width=1024, height=576, font.size=16) {
title <- ifelse(!is.null(name), name, p$labels$title)
if (is.null(title)) stop("Neither name nor title given")
filename <- paste0("Meade 4000 - ", title, ".png")
png(filename,width, height)
print(p + theme_bw(base_size=font.size))
dev.off()
}