For consistency, I now calculate the Sun's apparent position
correcting for aberration, for lunar eclipses and transits.
This didn't make much difference for accuracy.
Before correcting for Sun aberration:
$ ./ctest transit
C TransitFile(eclipse/mercury.txt ): PASS - verified 94, max minutes = 10.709, max sep arcmin = 0.2120
C TransitFile(eclipse/venus.txt ): PASS - verified 30, max minutes = 9.108, max sep arcmin = 0.6772
$ ./ctest -v lunar_fraction
C LunarFractionCase(2010-06-26) fraction error = 0.00900991
C LunarFractionCase(2012-06-04) fraction error = 0.00491535
C LunarFractionCase(2013-04-25) fraction error = 0.00143039
C LunarFractionCase(2017-08-07) fraction error = 0.00682336
C LunarFractionCase(2019-07-16) fraction error = 0.00572727
C LunarFractionCase(2021-11-19) fraction error = 0.00350680
C LunarFractionCase(2023-10-28) fraction error = 0.00370518
C LunarFractionCase(2024-09-18) fraction error = 0.00429906
C LunarFractionCase(2026-08-28) fraction error = 0.00322697
C LunarFractionCase(2028-01-12) fraction error = 0.00405870
C LunarFractionCase(2028-07-06) fraction error = 0.00857840
C LunarFractionCase(2030-06-15) fraction error = 0.00557106
C LunarFractionTest: PASS
After correcting for Sun aberration:
$ ./ctest transit
C TransitFile(eclipse/mercury.txt ): PASS - verified 94, max minutes = 10.709, max sep arcmin = 0.2120
C TransitFile(eclipse/venus.txt ): PASS - verified 30, max minutes = 9.108, max sep arcmin = 0.6772
$ ./ctest -v lunar_fraction
C LunarFractionCase(2010-06-26) fraction error = 0.00762932
C LunarFractionCase(2012-06-04) fraction error = 0.00606322
C LunarFractionCase(2013-04-25) fraction error = 0.00111560
C LunarFractionCase(2017-08-07) fraction error = 0.00571542
C LunarFractionCase(2019-07-16) fraction error = 0.00713913
C LunarFractionCase(2021-11-19) fraction error = 0.00298979
C LunarFractionCase(2023-10-28) fraction error = 0.00448445
C LunarFractionCase(2024-09-18) fraction error = 0.00367044
C LunarFractionCase(2026-08-28) fraction error = 0.00405559
C LunarFractionCase(2028-01-12) fraction error = 0.00347340
C LunarFractionCase(2028-07-06) fraction error = 0.00729982
C LunarFractionCase(2030-06-15) fraction error = 0.00680776
C LunarFractionTest: PASS
C function Astronomy_SearchLocalSolarEclipse now reports
obscuration for the peak of a solar eclipse seen at a given location.
Some of the test data from aa.usno.navy.mil looks suspiciously inaccurate.
I am finding better agreement with Fred Espenak's eclipsewise.com and
Xavier M. Jubier's xjubier.free.fr online calculators.
The larger obscuration differences are from aa.usno.navy.mil:
don@spearmint:~/github/astronomy/generate $ ./ctest -v solar_fraction
C GlobalAnnularCase(2023-10-14) obscuration error = 0.00009036, expected = 0.90638000, calculated = 0.90647036
C GlobalAnnularCase(2024-10-02) obscuration error = 0.00005246, expected = 0.86975000, calculated = 0.86980246
C GlobalAnnularCase(2027-02-06) obscuration error = 0.00007237, expected = 0.86139000, calculated = 0.86146237
C GlobalAnnularCase(2028-01-26) obscuration error = 0.00003656, expected = 0.84787000, calculated = 0.84790656
C GlobalAnnularCase(2030-06-01) obscuration error = 0.00008605, expected = 0.89163000, calculated = 0.89171605
C LocalSolarCase(2023-10-14) obscuration diff = 0.00006323, expected = 0.90638000, calculated = 0.90644323
C LocalSolarCase(2023-10-14) obscuration diff = -0.00521043, expected = 0.57800000, calculated = 0.57278957
C LocalSolarCase(2024-04-08) obscuration diff = 0.00000000, expected = 1.00000000, calculated = 1.00000000
C LocalSolarCase(2024-04-08) obscuration diff = 0.00304558, expected = 0.34000000, calculated = 0.34304558
C LocalSolarCase(2024-10-02) obscuration diff = 0.00007858, expected = 0.86975000, calculated = 0.86982858
C LocalSolarCase(2024-10-02) obscuration diff = -0.00343797, expected = 0.43600000, calculated = 0.43256203
C LocalSolarCase(2030-06-01) obscuration diff = 0.00007259, expected = 0.89163000, calculated = 0.89170259
C LocalSolarCase(2030-06-01) obscuration diff = -0.00059871, expected = 0.67240000, calculated = 0.67180129
C SolarFractionTest: PASS
I am going to rework using xjubier.free.fr in a subsequent commit.
Fixed bug in internal C function Obscuration().
It was not calculating obscuration correctly when
the second disc is completely inside the first disc,
i.e. the annular solar eclipse case.
Added C/C++ calculation of obscuration for global solar
eclipses that are total or annular at their peak
location and time. Obscuration is not calculated
for partial solar eclipses by SearchGlobalSolarEclipse.
Soon SearchLocalSolarEclipse will calculate obscuration
for partial solar eclipses at the geographic location
provided by the caller.
Starting to add support for calculating the intensity
of lunar eclipses and solar eclipses in terms of "obscuration".
This commit adds calculation of obscuration for lunar eclipses
in C/C++. The structure returned by SearchLunarEclipse and
NextLunarEclipse now includes an `obscuration` field whose value
is in the range [0, 1], indicating what fraction of the Moon's
apparent disc is covered by the Earth's umbra at the eclipse's peak.
I ported the NOVAS C 3.1 functions julian_date and cal_date to Python,
and removed the dependence on the standard datetime class for calculating UT.
Now we can create Time objects for a much wider range of year values.
Simplified the julian_date formula in C and C#.
In the Python version, I had to account for a difference
in the way integer division works for negative numbers.
In Python, integer division always rounds down, not toward
zero like it does in C/C#. So I reworked the formulas to
avoid dividing a negative integer (month-14), dividing the
positive quantity (14-month) instead and toggling addition
of the term with subtraction of the term.
I use the reworked (14-month) version in C and C# for consistency.
Also, the formatting of the formula was wacky and didn't make sense,
so now it easier to read and understand.
The Python regex for parsing dates has been expanded to allow
years before 0 and after 9999.
Allow converting Python Time to string for years before 0 and after 9999.
The .NET type System.DateTime is limited to the years 0000..9999.
The Astronomy Engine type AstroTime was using System.DateTime to
convert a (year, month, day, hour, minute, second) tuple into a
fractional day value. This caused an exception for years outside
the supported range 0000..9999.
I ported the NOVAS C 3.1 functions julian_date and cal_date to C#,
and removed the dependence on System.DateTime.
Now we can create AstroTime for a much wider range of year values.
Allow converting AstroTime to string for years before 0 and after 9999.
In the unit tests for searching forward and backward
for moon phases, in addition to new moons, also test
first quarter, full moon, and third quarter.
Verify that forward and backward searches work for
100 start times between a single pair of consecutive events.
The following Python functions now support searching
in forward or reverse chronological order:
SearchRiseSet
SearchAltitude
SearchHourAngle
Made some minor performance improvements to the
other implementations: return sooner if we
go past time window.
The following C# functions now support searching
in forward or reverse chronological order:
Astronomy.SearchRiseSet
Astronomy.SearchAltitude
Astronomy.SearchHourAngle
Also fixed places where I forgot to update documentation
for the corresponding changes to the C code.
The following C functions now support searching
in forward or reverse chronological order:
Astronomy_SearchRiseSet
Astronomy_SearchAltitude
Astronomy_SearchHourAngleEx
The function Astronomy_SearchHourAngleEx replaces
Astronomy_SearchHourAngle, adding a new `direction` parameter.
A #define for Astronomy_SearchHourAngle preserves backward
compatibility for older code.
Implementation notes:
Astronomy_SearchRiseSet and Astronomy_SearchAltitude used
to call a private function InternalSearchAltitude.
That function has been split into two functions:
BackwardSearchAltitude and ForwardSearchAltitude,
for searching both directions in time.
Fixed a bug where it was possible to report a successful
altitude event that went outside the time limit specified
by `limitDays`.
The quadratic interpolator used by `Search` was returning
an unused output: `x`. Search does not need this dimensionless
value; it only cares about the time solution `t` and the slope
of the function at `t`. Removed `x` from the return value
to make slightly smaller/faster code.
Enhanced the Kotlin function searchMoonPhase
to allow searching forward in time when the `limitDays`
argument is positive, or backward in time when `limitDays`
is negative.
Added unit test "moon_reverse" to verify this new feature.
Enhanced the Python function SearchMoonPhase
to allow searching forward in time when the `limitDays`
argument is positive, or backward in time when `limitDays`
is negative.
Added unit test "moon_reverse" to verify this new feature.
Enhanced the JavaScript function Astronomy.SearchMoonPhase
to allow searching forward in time when the `limitDays`
argument is positive, or backward in time when `limitDays`
is negative.
Added unit test "moon_reverse" to verify this new feature.
Enhanced the C# function Astronomy.SearchMoonPhase
to allow searching forward in time when the `limitDays`
argument is positive, or backward in time when `limitDays`
is negative.
Added unit test "moon_reverse" to verify this new feature.
Enhanced the C function Astronomy_SearchMoonPhase
to allow searching forward in time when the `limitDays`
argument is positive, or backward in time when `limitDays`
is negative.
Added unit test "moon_reverse" to verify this new feature.
The C version of Astronomy Engine does not work correctly
when gcc "fast math" optimizations are enabled.
The problem is that Astronomy Engine uses NAN values to
represent invalid/uninitialized floating point numbers.
The -Ofast option breaks the ability of the runtime to
check for NAN values, resulting in multiple failures
and incorrect behaviors at runtime.
Added a compile-time check for the __FAST_MATH__ preprocessor
symbol, which gcc defines to signal that the optimization
was enabled. If detected, this results in a compiler error
to make it obvious that something is wrong before invalid
code would be executed.
This is not an ideal fix for two reasons:
1. I don't know if this will detect similar problems for
other compilers than gcc.
2. If individual risky math optimizations are enabled, instead
of the combination of options included in -Ofast, the
__FAST_MATH__ preprocessor symbol will not be defined
and no compiler error will occur. I could not find a
way to detect individual risky optimizations.
However, this change is much better than nothing, and
hopefully it will prevent most cases of overly-aggressive
optimization.
I encountered a build/test failure in the Kotlin
code due to the JVM running out of memory.
I configured gradle to allow using more memory:
1GB instead of the default 256MB.
Definition of vsopModel constant on Body enum items constructors
makes cyclic dependency with constants defined later in the code
and makes application crash when things are not initiated in the
correct order.
This fixes the issue by turning vsopModel into a property which
will have almost the same internal API for the rest of the code
and resolves crashes I'm getting when certain part of my app
is initiated sooner than usual.
GitHub user `hidp123` submitted the following pull request:
https://github.com/cosinekitty/astronomy/pull/240
The problem was I had documentation for the Python enum
`Refraction` where I incorrectly wrote `Refraction.None`
instead of the correct name `Refraction.Airless`.
The fix in the pull request was correct, but it was
applied to generated source code, so it did not correctly
update the template file or the online documentation.
This commit fixes the mistake in all the affected files.
The JavaScript functions were appearing in unsorted
order in the markdown documentation.
The `jsdoc2md` tool does not have an option for sorting them.
So I wrote a new script `sort_js_functions.py` that post-
processes the markdown to sort the functions.
It turns out that "sed" does not work on Mac OS,
and I wasn't even trying to patch the version
numbers on Windows. I decided to write a Python
program for this task, so it will work identically
on all 3 operating systems.
Added a new file generate/version.txt that contains
the current Astronomy Engine version number.
Now when I run the build/test process, the version
number is patched in all the places it needs to
be changed to keep all the packages and documentation
up to date.
This means when I want to change the Astronomy Engine
version number, I just need to edit version.txt, then
execute the generate/run script.
Provide shield.io badges for pypi, npm, and nuget packages.
On the main README page, moved the badges into the supported
languages grid.
Added link and badge on each language documentation page.
Now that I have retargeted astronomy.csproj from
net5.0 to netstandard2.0, there are a couple of
other little improvements that are now possible:
1. In my manual Framework 4 test project, instead
of directly pulling in the source file astronomy.cs,
add astronomy.csproj as a project reference.
This demonstrates that the same binary astronomy.dll
works in both Framework and Core.
2. Now there is no need/use for conditional compilation
directives in the Astronomy.CubeRoot function.
Instead, always use my own implementation since the
Math.Cbrt function is never available.
From a testing standpoint, this was probably
the better option all along.
https://www.nuget.org/packages/CosineKitty.AstronomyEngine/2.1.2
This is my first attempt at publishing a NuGet package.
I have never done this before, so I'm not sure it is going to work.
Changed astronomy.csproj to target netstandard2.0, which still
works fine with all my net6.0 unit tests.