Skip to content

Commit

Permalink
String time functions
Browse files Browse the repository at this point in the history
  • Loading branch information
attipaci committed Jan 27, 2025
1 parent 399ca44 commit 6500a00
Show file tree
Hide file tree
Showing 7 changed files with 508 additions and 46 deletions.
26 changes: 21 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,27 @@ Upcoming feature release, expected around 1 May 2025.
### Fixed

- #116: `transform_cat()` to update parallax to the recalculated value when precessing or changing epochs.

- `julian_date()` to work with negative years (for B.C. dates). E.g. the year -1 denotes 1 BC.

### Added

- #114: New `novas_lsr_to_ssb_vel()` can be used to convert velocity vectors referenced to the LSR to Solar-System
Barycentric velocities. And, `novas_ssb_to_lsr_vel()` to provide the inverse conversion.

- New `novas_hms_hours(const char *str)` and `novas_dms_degrees(const char *str)` convenience functions to make it
easier to parse HMS or DMS based time/angle values, returning the result in units of hours or degrees,
appropriately for use in SuperNOVAS.
- New `novas_hms_hours()` and `novas_dms_degrees()` convenience functions to make it easier to parse HMS or DMS based
time or angle values, returning the result in units of hours or degrees, appropriately for use in SuperNOVAS, and

- New `novas_parse_date()` / `novas_parse_date_format()` to parse date/time specifications, `novas_parse_dms()` and
`novas_parse_hms()` to return hours and degrees for HMS and DMS specifications, as well as the updated parse
position.

- New `novas_set_string_time()` and `novas_set_mjd()` funtions for easier time setting using previously configured
providers of leap seconds and UT1-UTC time difference via `novas_set_leap_provider()` and
`novas_set_dut1_provider()`. (The providers can be accessed via `novas_get_leap_provider()` and
`novas_get_dut1_provider()`.

- New `novas_iso_timestamp()` to print UTC timestamps in ISO date format with millisecond precision.

- New `novas_frame_lst()` convenience function to readily return the Local (apparent) Sidereal Time for a given
Earth-based observing frame.
Expand Down Expand Up @@ -64,12 +76,16 @@ Upcoming feature release, expected around 1 May 2025.
To run the SuperNOVAS benchmarks, simply `make benchmark` in the distribution directory.

### Changed

- Updated `README.md` for v1.3 and benchmarks, including comparisons to __astropy__.

- In reduced accuracy mode apply gravitational deflection for the Sun only. In prior versions, deflection corrections
were applied for Earth too. However, these are below the mas-level accuracy promised in reduced accuracy mode, and
without it, the calculations for `place()` and `novas_sky_pos()` are significantly faster.

- Modified `julian_date()` to add range checking for month and day arguments, and return NAN (with errno set to
EINVAL) if the input values are invalid.

- Updated `README.md` for v1.3 and benchmarks, including comparisons to __astropy__.



## [1.2.0] - 2025-01-15
Expand Down
34 changes: 30 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The primary goal of SuperNOVAS is to improve on the stock NOVAS C library via:

- Fixing [outstanding issues](#fixed-issues).
- Improved [API documentation](https://smithsonian.github.io/SuperNOVAS/apidoc/html/files.html).
- [Faster calculations](#benchmarks)
- [Faster calculations](#benchmarks).
- [New features](#added-functionality).
- [Refining the API](#api-changes) to promote best programming practices.
- [Thread-safe calculations](#multi-threading).
Expand Down Expand Up @@ -158,6 +158,8 @@ provided by SuperNOVAS over the upstream NOVAS C 3.1 code:

- [__v1.3__] `transform_cat()` to update parallax to the recalculated value when precessing or changing epochs.

- [__v1.3__] `julian_date()` to work with negative (B.C.) years also. E.g. the year -1 denotes 1 BC.


-----------------------------------------------------------------------------

Expand Down Expand Up @@ -538,6 +540,12 @@ or, for the best precision we may do the same with an integer / fractional split
novas_set_split_time(NOVAS_TAI, ijd_tai, fjd_tai, 37, 0.114, &obs_time);
```
or, you can use a string date, such as an ISO timestamp:
```c
novas_set_string_time(NOVAS_UTC, "2025-01-26T22:05:14.234+0200", 37, 0.042, &obs_time);
```


#### Set up the observing frame

Expand Down Expand Up @@ -1131,9 +1139,19 @@ one minute.
- New `novas_lsr_to_ssb_vel()` can be used to convert velocity vectors referenced to the LSR to Solar-System
Barycentric velocities. And, `novas_ssb_to_lsr_vel()` to provide the inverse conversion.

- New `novas_hms_hours(const char *str)` and `novas_dms_degrees(const char *str)` convenience functions to make it
easier to parse HMS or DMS based time/angle values, returning the result in units of hours or degrees,
appropriately for use in SuperNOVAS.
- New `novas_hms_hours()` and `novas_dms_degrees()` convenience functions to make it easier to parse HMS or DMS based
time or angle values, returning the result in units of hours or degrees, appropriately for use in SuperNOVAS, and

- New `novas_parse_date()` / `novas_parse_date_format()` to parse date/time specifications, `novas_parse_dms()` and
`novas_parse_hms()` to return hours and degrees for HMS and DMS specifications, as well as the updated parse
position.

- New `novas_set_string_time()` and `novas_set_mjd()` funtions for easier time setting using previously configured
providers of leap seconds and UT1-UTC time difference via `novas_set_leap_provider()` and
`novas_set_dut1_provider()`. (The providers can be accessed via `novas_get_leap_provider()` and
`novas_get_dut1_provider()`.

- New `novas_iso_timestamp()` to print UTC timestamps in ISO date format with millisecond precision.

- New `novas_frame_lst()` convenience function to readily return the Local (apparent) Sidereal Time for a given
Earth-based observing frame.
Expand Down Expand Up @@ -1250,6 +1268,14 @@ one minute.

- [__v1.3__] Modified `place()` and `novas_geom_posvel()` to use physical velocity, rather than projected movement,
for calculating radial velocities for sidereal sources.

- [__v1.3__] In reduced accuracy mode apply gravitational deflection for the Sun only. In prior versions, deflection
corrections were applied for Earth too. However, these are below the mas-level accuracy promised in reduced
accuracy mode, and without it, the calculations for `place()` and `novas_sky_pos()` are significantly faster.

- [__v1.3__] Modified `julian_date()` to allow BC dates as negative years, e.g. use -1 to indicate 1 BC. Also add
range checking for month and day arguments, and return NAN (with errno set to EINVAL) if the input values are
invalid.


-----------------------------------------------------------------------------
Expand Down
26 changes: 26 additions & 0 deletions include/novas.h
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,19 @@ typedef struct {
novas_observable accel; ///< [deg/s<sup>2</sup>,AU/s<sup>2</sup>,1/s<sup>2</sup>] Apparent position acceleration.
} novas_track;

/**
* The general order of date components for parsing.
*
* @since 1.3
* @author Attila Kovacs
*
* @sa novas_parse_date_format()
*/
enum novas_date_format {
NOVAS_YMD = 0, ///< year, then month, then day.
NOVAS_DMY, ///< day, then month, then year
NOVAS_MDY ///< month, then day, then year
};


short app_star(double jd_tt, const cat_entry *star, enum novas_accuracy accuracy, double *ra, double *dec);
Expand Down Expand Up @@ -1712,6 +1725,10 @@ double novas_hms_hours(const char *hms);

double novas_dms_degrees(const char *dms);

double novas_parse_hms(const char *str, char **tail);

double novas_parse_dms(const char *str, char **tail);

double novas_hpa(double az, double el, double lat);

double novas_epa(double ha, double dec, double lat);
Expand All @@ -1730,6 +1747,7 @@ int novas_xyz_to_los(const double *xyz, double lon, double lat, double *los);

int novas_xyz_to_uvw(const double *xyz, double ha, double dec, double *uvw);

// in frames.c
double novas_frame_lst(const novas_frame *frame);

double novas_rises_above(double el, const object *source, const novas_frame *frame, RefractionModel ref_model);
Expand All @@ -1748,6 +1766,14 @@ int novas_hor_track(const object *source, const novas_frame *frame, RefractionMo

int novas_track_pos(const novas_track *track, const novas_timespec *time, double *lon, double *lat, double *dist, double *z);

// in timescale.c
double novas_parse_date(const char *date, char **tail);

double novas_parse_date_format(enum novas_date_format format, const char *date, char **tail);

int novas_iso_timestamp(const novas_timespec *time, char *dst, int maxlen);



// <================= END of SuperNOVAS API =====================>

Expand Down
29 changes: 26 additions & 3 deletions src/novas.c
Original file line number Diff line number Diff line change
Expand Up @@ -6655,17 +6655,25 @@ double refract(const on_surface *location, enum novas_refraction_model option, d
* can be based on any UT-like time scale (UTC, UT1, TT, etc.) - output Julian date will have
* the same basis.
*
* NOTES:
* <ol>
* <li>Added argument range checking in v1.3.0, returning NAN if the month or day are out of
* the normal range (for a leap year).</li>
* </ol>
*
* REFERENCES:
* <ol>
* <li>Fliegel, H. & Van Flandern, T. Comm. of the ACM, Vol. 11, No. 10, October 1968, p.
* 657.</li>
* </ol>
*
* @param year [yr] Gregorian calendar year
* @param year [yr] Gregorian calendar year (BC dates are 0 or negative, with 0 corresponding
* to 1 BC, hence X BC is `1 - X`).
* @param month [month] Gregorian calendar month [1:12]
* @param day [day] Day of month [1:31]
* @param hour [hr] Hour of day [0:24]
* @return [day] the fractional Julian date for the input calendar date
* @return [day] the fractional Julian date for the input calendar date, ot NAN if
* month or day components are out of range.
*
* @sa cal_date()
* @sa get_utc_to_tt()
Expand All @@ -6674,7 +6682,22 @@ double refract(const on_surface *location, enum novas_refraction_model option, d
*
*/
double julian_date(short year, short month, short day, double hour) {
long jd12h = day - 32075L + 1461L * (year + 4800L + (month - 14L) / 12L) / 4L + 367L * (month - 2L - (month - 14L) / 12L * 12L) / 12L
static const char *fn = "julian_date";
static const int md[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

long jd12h;

if(month < 1 || month > 12) {
novas_error(0, EINVAL, fn, "invalid month: %d, expected 1-12", month);
return NAN;
}

if(day < 1 || day > md[month]) {
novas_error(0, EINVAL, fn, "invalid day-of-month: %d, expected 1-%d", day, md[month]);
return NAN;
}

jd12h = day - 32075L + 1461L * (year + 4800L + (month - 14L) / 12L) / 4L + 367L * (month - 2L - (month - 14L) / 12L * 12L) / 12L
- 3L * ((year + 4900L + (month - 14L) / 12L) / 100L) / 4L;
return jd12h - 0.5 + hour / DAY_HOURS;
}
Expand Down
Loading

0 comments on commit 6500a00

Please sign in to comment.