We load two packages, our ‘photobiology’ and ‘lubridate’, as they will be used in the examples.
library(photobiology)
library(lubridate)
##
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
##
## date
The functions and methods described in this section return either values that represent angles or times. In the current version angles are always expressed in degrees. In the case of times, the unit of expression, can be changed through parameter unit.out
which accepts the following arguments "datetime"
, "hour"
, "minute"
, "second"
. For backwards compatibility "date"
is also accepted as equivalent to "datetime"
but deprecated.
In photobiology research we sometimes need to calculate the position on the sun at arbitrary geographic locations and times. The function sun_angles
returns the azimuth in degrees eastwards, altitude in degrees above the horizon, solar disk diameter in degrees and sun to earth distance in astronomical units. The time should be a POSIXct
vector, possibly of length one. The easiest way create date and time constant values is to use package lubridate
.
geocode
most functions also had the redundant formal parameters lon
and lat
which were removed in version 0.9.12. This change may require users’ scripts to be revised.
sun_angles(now(), geocode = data.frame(lat = 34, lon = 0))
## time tz solartime longitude latitude address azimuth
## 1 2016-12-18 00:18:58 22:22:16 0 34 <NA> 289.9919
## elevation
## 1 -66.17556
sun_angles(ymd_hms("2014-01-01 0:0:0", tz = "UTC") + hours(1:3))
## time tz solartime longitude latitude address azimuth
## 1 2014-01-01 01:00:00 UTC 00:56:31 0 51.5 Greenwich 26.26506
## 2 2014-01-01 02:00:00 UTC 01:56:30 0 51.5 Greenwich 49.24212
## 3 2014-01-01 03:00:00 UTC 02:56:29 0 51.5 Greenwich 66.84595
## elevation
## 1 -59.47735
## 2 -53.73359
## 3 -45.80941
When spectra contain suitable metadata, the position of the sun for the spectral irradiance data measurement can be easily obtained.
sun_angles(getWhenMeasured(sun.spct), geocode = getWhereMeasured(sun.spct))
## time tz solartime longitude latitude
## 1 2010-06-22 09:51:00 UTC 11:28:50 24.96424 60.20942
## address azimuth elevation
## 1 Kumpula, Helsinki, FI 168.122 52.82309
The object to be supplied as argument for geocode
is a data frame with variables lon
and lat
. This matches the return value of function ggmap::geocode()
, function that can be used to find the coordinates using any address entered as a character string understood by the Google maps API.
Functions sunrise_time
, sunset_time
, noon_time
, day_length
and night_length
have all the same parameter signature. In addition, function day_night
returns a data frame containing all the quantities returned by the other functions. They are all vectorized for the date
and geocode
parameters.
We create a vector of dates to use in the examples—default time zone of ymd
is UTC.
dates <- seq(from = ymd("2015-03-01"), to = ymd("2015-07-1"), length.out = 3)
Default latitude is zero (the Equator), the default longitude is zero (Greenwich), and default time zone for the functions in the photobiology
package is in most cases the time zone returned by the operating system, but values are stored in time zone "UTC"
. Be also aware that for summer dates the times are formatted for printing accordingly. In the examples below this can be recognized for example, by the time zone being reported as EEST instead of EET for Eastern Europe.
noon_time(dates, tz = "UTC", data.frame(lat = 34, lon = 0))
## [1] "2015-03-01 12:12:20 UTC" "2015-05-01 11:57:06 UTC"
## [3] "2015-07-01 12:03:52 UTC"
noon_time(dates, tz = "CET", data.frame(lat = 34, lon = 0))
## [1] "2015-03-01 13:12:20 CET" "2015-05-01 13:57:06 CEST"
## [3] "2015-07-01 14:03:52 CEST"
day_night(dates, geocode = data.frame(lat = 60, lon = 0))
## day tz twilight.rise twilight.set longitude latitude
## 1 2015-03-01 Europe/Helsinki none none 0 60
## 2 2015-05-01 Europe/Helsinki none none 0 60
## 3 2015-07-01 Europe/Helsinki none none 0 60
## address sunrise noon sunset daylength nightlength
## 1 <NA> 9.082918 14.20557 19.3282169 10.245299 13.754701
## 2 <NA> 7.086868 14.95169 22.8165183 15.729651 8.270349
## 3 <NA> 5.892324 15.06447 0.2366178 -5.655707 29.655707
he default for date
is the current day.
sunrise_time(geocode = data.frame(lat = 60, lon = 0))
## [1] "2016-12-18 11:00:33 EET"
Both latitude and longitude should be supplied through geocode
, but be aware that if the returned value is desired in the local time coordinates of the argument passed to gocode
, the time zone should match the geographic coordinates.
sunrise_time(today("UTC"), tz = "UTC", geocode = data.frame(lat = 60, lon = 0))
## [1] "2016-12-17 08:59:46 UTC"
sunrise_time(today("EET"), tz = "EET", geocode = data.frame(lat = 60, lon = 25))
## [1] "2016-12-18 09:20:33 EET"
Southern hemisphere latitudes as well as longitudes to the West of the Greenwich meridian should be supplied as negative numbers.
sunrise_time(dates, geocode = data.frame(lat = 60, lon = 0))
## [1] "2015-03-01 08:58:05 EET" "2015-05-01 06:57:19 EEST"
## [3] "2015-07-01 05:42:30 EEST"
sunrise_time(dates, geocode = data.frame(lat = -60, lon = 0))
## [1] "2015-03-01 07:12:45 EET" "2015-05-01 10:41:14 EEST"
## [3] "2015-07-01 12:03:42 EEST"
The angle used in the twilight calculation can be supplied, either as the name of a standard definition, or as an angle in degrees (negative for sun positions below the horizon). Positive angles can be used when the time of sun occlusion behind a building, mountain, or other obstacle needs to be calculated.
sunrise_time(today("EET"), tz = "EET",
geocode = data.frame(lat = 60, lon = 25),
twilight = "civil")
## [1] "2016-12-18 08:22:49 EET"
sunrise_time(today("EET"), tz = "EET",
geocode = data.frame(lat = 60, lon = 25),
twilight = -10)
## [1] "2016-12-18 07:44:09 EET"
sunrise_time(today("EET"), tz = "EET",
geocode = data.frame(lat = 60, lon = 25),
twilight = +12)
## [1] NA
Parameter unit.out
can be used to obtain the returned value expressed as time-of-day in hours, minutes, or seconds since midnight.
sunrise_time(today("EET"),
tz = "EET",
geocode = data.frame(lat = 60, lon = 25),
unit.out = "hours")
## [1] 9.342699
Functions day_length
and night_length
return by default the length of time in hours.
day_length(dates, geocode = data.frame(lat = 60, lon = 25))
## [1] 10.47461 15.99267 18.71209
night_length(dates, geocode = data.frame(lat = 60, lon = 25))
## [1] 13.525392 8.007326 5.287909
Function day_night
returns a data frame.
day_night(dates,
geocode = data.frame(lat = 60, lon = 25))
## day tz twilight.rise twilight.set longitude latitude
## 1 2015-03-01 Europe/Helsinki none none 25 60
## 2 2015-05-01 Europe/Helsinki none none 25 60
## 3 2015-07-01 Europe/Helsinki none none 25 60
## address sunrise noon sunset daylength nightlength
## 1 <NA> 7.416251 12.53890 17.66155 10.24530 13.754701
## 2 <NA> 5.420201 13.28503 21.14985 15.72965 8.270349
## 3 <NA> 4.225658 13.39780 22.56995 18.34429 5.655707
day_night(dates,
geocode = data.frame(lat = 60, lon = 25),
unit.out = "datetime")
## day tz twilight.rise twilight.set longitude latitude
## 1 2015-03-01 Europe/Helsinki none none 25 60
## 2 2015-05-01 Europe/Helsinki none none 25 60
## 3 2015-07-01 Europe/Helsinki none none 25 60
## address sunrise noon sunset
## 1 <NA> 2015-03-01 07:24:58 2015-03-01 12:32:20 2015-03-01 17:39:41
## 2 <NA> 2015-05-01 05:25:12 2015-05-01 13:17:06 2015-05-01 21:08:59
## 3 <NA> 2015-07-01 04:13:32 2015-07-01 13:23:52 2015-07-01 22:34:11
## daylength nightlength
## 1 10.24530 13.754701
## 2 15.72965 8.270349
## 3 18.34429 5.655707
In field research it is in many cases preferable to sample or measure, and present and plot data based on local solar time. Two functions are provided. They differ in the value returned, either a time of day in hours, or a date.
Paris.geo <- data.frame(lon = 2.352222, lat = 48.85661, address = "Paris")
Paris.time <- ymd_hms("2016-09-30 06:00:00", tz = "UTC")
solar_time(Paris.time, geocode = Paris.geo)
## [1] "06:19:33"
solar_time(Paris.time, geocode = Paris.geo, unit.out = "datetime")
## [1] "2016-09-30 06:19:33 solar"
my.solar.t <- solar_time(Paris.time, geocode = Paris.geo)
is.solar_time(my.solar.t)
## [1] TRUE
is.numeric(my.solar.t)
## [1] TRUE
my.solar.d <- solar_time(Paris.time, geocode = Paris.geo, unit.out = "datetime")
is.solar_date(my.solar.d)
## [1] TRUE
is.timepoint(my.solar.d)
## [1] TRUE
Function as_tod()
facilitates conversion of R’s time date objects into a numeric value representing the time of day in one of hour, minute or second as unit of expression.
times <- now() + days(0:1)
times
## [1] "2016-12-18 00:18:58 EET" "2016-12-19 00:18:58 EET"
as_tod(times)
## [1] 0.3163843 0.3163843
as_tod(times, unit.out = "minutes")
## [1] 18.98306 18.98306