Planning and logging astronomical observations via computational astronomy, open data, and public APIs.
My final dissertation document can be downloaded using the following link. Please note that this document has been purposely exported with navigation data and clickable cross references to make reading easier as it is almost 240 pages long. To make use of these, the file is best viewed in a web browser or a dedicated PDF reader as they cannot be used in GitHub's native viewer.
I also created a demo video so you can get a better idea of how everything fits together:
- Project goal
- Project architecture
- Deployment
- Observation reports and computational astronomy
- Testing
- Quick source tree links
"The main objective of AstroCue was to provide a set of integrated and unified web facilities for the automated planning and subsequent user logging of astronomical observations."
"It would consider geographic and celestial coordinates, local time, weather, and light pollution data to provide predicted best viewing times over a short upcoming period, and then allow users to log any observations that were made."
Overall, AstroCue was a distributed client-server system. The server (this repository) is an ASP .NET Core web API (C#), and the AstroCue Client was a Next.js/React application (TypeScript).
In the broadest sense, AstroCue followed the MVC (Model-View-Controller) pattern, but with a few noteworthy alterations:
-
The view layer was actually a separate codebase on a separate domain (see the AstroCue Client).
-
The server, on top of models and controllers, introduced a service layer. This layer housed data access code and a large portion of the business logic. These service classes were specific to a task (i.e.
EmailService
orUserService
, and had accompanying interfaces such asIEmailService
andIUserService
). These service classes were reusable and maintainable as they were fine grained and had their concrete behaviors offered to client classes through their interfaces that were registered with a dependency injection container.This is similar to Martin Fowler's P of EAA Catalog - Service Layer.
The server contains many classes across many packages, and during planning, a class diagram was created to aid the structure as the codebase grew. While the actual structure ended up being slightly different than what is depicted here, it adhered enough to still represent the state on a large scale.
(SVG image - open in new tab and zoom for details. Quality will not be lost).
Entities
| 'Models' from MVCControllers
| C from MVCCore
| Integral parts of an ASP .NET Core web APIAstronomy
| Computational astronomy calculationsServices
| Services as mentioned in section 2.1Data
| Astronomical catalogue parsers, environment variables, and EF Core database context
The server was deployed to Microsoft Azure. It consisted of an App Service instance, a database (Azure SQL Server), and a blob storage instance. The App Service was where the server executable itself ran, the database was where it persisted all of its data, and the blob storage was somewhat separate, serving as a hosting area for resources (images etc...) delivered via emails to users.
Below is a deployment diagram representing this setup. It also includes the third party APIs and an example of a client.
Below is the Entity Relationship Diagram created by Microsoft SQL Server Management Studio that shows the different database tables comprising the production database. Note there are several tables created by Hangfire that aren't included for brevity.
AstroCueUsers
| Users tableObservations
| Astronomical observations (between locations and objects)__EFMigrationsHistory
| Migration history stored by Entity Framework CoreAstronomicalObjects
| Stars and deep sky objects (>125,000 rows)ObservationLocations
| Locations added by users denoting where they go to observeObservationLogs
| Stores observation logs created by users againstReports
Reports
| Stores observation reports generated by AstroCue's algorithms
The main purpose of AstroCue was to provide users with reports about when the best time to observe certain objects would be based on the relative conditions of the next few days at their observation locations. The main form of the reports were periodic emails sent to the email addresses that users used when signing up.
The server automatically generates and sends out these emails at 16:00 UTC every Monday and Thursday, but users can also request for their reports to be generated on demand. For each observation
(a combination of one of their observation locations and an astronomical object) owned by a given user, a single report would be generated. All of the reports for a given run are collated and sent in a single email.
Observation report emails look as follows:
At the core of the computational astronomy algorithms implemented by AstroCue is a transformation between the equatorial and horizontal coordinate systems.
For an introduction to these systems, a section of my report has been exported for easy access and can be found here:
Introduction to Celestial Coordinate Systems.pdf
This transformation allows the server to take the fixed coordinates of astronomical objects inside astronomical catalogues, and turn them into relative & local coordinates that are specific to a given location at a given time. In most typical cases, this calculation is used where the 'given time' is the best rated time to observe based on analysis of upcoming weather at the user's observation location.
This transformation is also used to calculate Diurnal Motion. Most people have seen long exposure pictures such as this:
Image from homeofphysics Wiki.
This is Diurnal Motion in action - the apparent motion of astronomical objects across the sky during the night. You can imagine that across a full day, objects will complete a full circle, appearing to revolve around the northern and southern pole stars.
AstroCue use Diurnal Motion as a measurement of whether a given object will rise above the horizon at a given location. If you simulate a full 24hr cycle of this motion and look at the altitude values (degrees above or below the horizon) of the object at each hour, if any of them are >0°, then you can say that the object is certain* to rise above the horizon at that location.
*Note that this doesn't take into account atmospheric refraction or the time of day. Refraction was not considered, but making this calculation relative to the night time hours at a given location would be a simple addition to the code in its current state.
AstroCue was tested via unit tests and routine use of Visual Studio's Maintainability Index feature. Unit tests covered important logic where appropriate (and where time permitted), along with acting as a way to support my main report when I asserted that certain technical objectives I'd set myself had actually been met.
Unit tests made use of a few libraries. Notably was MSTest for the actual testing framework, Moq for mocking, and MockHTTP for testing of some external HTTP behaviour.
Use these links to quickly navigate to a point of interest in the repository.
- 💉 Dependency injection - Container setup | Example client
- 💃 Models - (MVC) - referred to as 'entities' in this codebase
- 🎮 Controllers - (MVC)
- 🌟 Computational astronomy - Celestial coordinate transforms | Diurnal motion
- 💡 Light pollution calculations using the Bortle Scale
- ⚙️ Services for:
- ✉️ Sending emails via the MailGun API
- 🗺️ Retrieving mapping data via the MapBox API
- 🌧️ Retrieving weather data via the OpenWeatherMap API
- 💡 Calculating arbitrary light pollution levels
- 📋 Generating AstroCue's reports
- 🗂️ Parsing astronomical catalogues
- 💾 EF Core database context
- 🧪 Unit tests - includes dependency mocking and in-memory database testing