In all four versions of Astronomy Engine (C, C#, JavaScript, and Python),
starting a search for a full moon near December 19, 2020 would fail.
I added a unit test to all four languages and it failed consistently
across them all.
The root cause: I was too optimistic about how narrow I could make
the window around the approximate moon phase time in the
SearchMoonPhase functions. Finding the exact moon phase time failed
because it was outside this excessively small window around the approximate
time. I increased the window from 1.8 days to 3.0 days.
This should handle all cases with minimal impact on performance.
Now all four of the new unit tests pass.
Ported Pluto integrator to C#.
Along the way, I noticed that I had VSOP87 latitude and longitude
swapped in such a way that they worked, but were labeled wrong.
This confused me quite a bit as I tried to implement functions
to calculate the derivatives of the VSOP87 spherical coordinates.
Fixed this in the code generator and the C and C# template files.
In the JavaScript version, check throughout for valid
finite numeric/boolean values as needed.
This should make debugging a lot easier for everybody.
In the unit tests for all languages, also check for infinite
results, not just NaN.
I discovered that JS Astronomy.NextLocalSolarEclipse() was broken:
It was trying to call a nonexistent function.
Fixed it, and added unit test that would have caught the breakage.
Fixed mistakes in JS documentation for the field names of the
Observer class.
Now that I have switched to TOP2013 for calculating Pluto's
position in the C# code, there is no need for the unit test
to handle errors for out-of-bound time coordinate.
Also corrected code generator to output term coefficients
in scientific notation. In the C code, it was dropping signficant
digits by outputting in fixed point notation.
All the other languages have a lookup table that allows
any specific test to be run by name, or all tests to be run
using "all" as the name. Now the C# unit test does the same.
unit_test_c was not testing local solar eclipses.
C ParseDate() was not scanning seconds. This caused
discrepancies between C and C# results.
It was also failing to verify the Z on the end.
I had to increase certain error tolerances in the unit tests.
Reworked the unit tests to make more sense by waiting until
each language step is done to check against each other.
That way I can run a single language step independently.
Can now calculate the heliocentric Solar System Barycenter (SSB)
and Earth/Moon Barycenter (EMB).
Changes made in C, C#, JavaScript and Python:
Added new body codes SSB, EMB.
Added support for calculating both in HelioVector functions.
Verified that all calculations match NOVAS.
Verified that all calculations match each other across languages.
Because I had to tweak models to get better planet apsis predictions,
it caused slight changes in other calculations that tripped
unit test errors. These are all still within safe values, so
I relaxed the ones that failed.
Include an extra 4 terms in the radial component of the VSOP
model for Neptune. The code automatically picks the 4 terms
that maximize the time derivative's highest possible contribution.
Removed redundant refraction calculations from Astronomy.Horizon().
Added a unit test that InverseRefractionAngle() converges and calculates
an accurate inverse of RefractionAngle().
More work on new functions for converting orientation systems.
Changed a few classes to structs for memory allocation efficiency.
Moved stuff around in astronomy.cs so the Astronomy class comes
last. This is helpful when I want to add new functions, so I
don't have to search for the end of the class.
I was going to write a Python program to parse the
xml file generated by the C# compiler.
The problem is it does not contain enough information
about types, as explained here:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc/how-to-use-the-xml-documentation-features
"The XML file does not provide full information about the type and members
(for example, it does not contain any type information).
To get full information about a type or member, the documentation file
must be used together with reflection on the actual type or member."
So that means I will end up writing the documentation generator in C#
and using reflection along with the XML file to generate Markdown.