This will be my informal introduction to sim-transit-lc, an open source toolset I've been working on. The toolset is meant to be a general purpose light curve analysis and optimization system, but today we'll only be looking at one built-in transit type: ringed planets.

The D792 dip of Boyajian's star (or KIC 8462852) is one of the most peculiar ever recorded. It's not only considerably deeper than most exoplanetary dips, but it also doesn't have the usual V or U shape; plus it's asymmetric.

Ballesteros et al. (2017) came up with a clever idea to try to explain its asymmetry, by means of a planet with a ring system that has a slight tilt and obliquity relative to the orbital plane of the planet. The Trojan Asteroids hypothesis of Ballesteros et al. fell out of favor shortly after it came out (because Boyajian's star has experienced a number of new dipping events, which are at odds with the hypothesis) but the general idea of using ring systems to explain D792 and other dips remains relevant, in my opinion.

We will use sim-transit-lc's optimizer tool, called lc-opt. You provide the tool an "optimization specification" written in JSON, and then sim-transit-lc's optimization algorithm does the rest. The JSON file that gave me the best results looks like this:
    "widthPixels": 400,
    "heightPixels": 100,
    "orbitPeriod": 1461,
    "orbitRadius": 850,
    "orbitRadiusFlexibility": 0.1,
    "limbDarkeningParams": [ 0.30, 0.30 ],
    "method": {
        "type": "code",
        "className": "GradientRingPlanetBuilder",
        "properties": {
            "originXBounds": [ -2.3, -0.7 ],                    
            "impactParameterBounds": [ 0.3, 1.3 ],    
            "tiltBounds": [ 0.02, 0.20 ],                    
            "obliquityBounds": [ 0.02, 0.1 ],                    
            "planetRadiusBounds": [ 0.05, 0.50 ],            
            "ringInnerRadiusBounds": [ 0.05, 2.0 ],        
            "ringOuterRadiusBounds": [ 3.0, 20.0 ],        
            "ringHalfOpacityRadiusBounds": [ 1.0, 10.0 ],    
            "ringMaxOpacityBounds": [ 0.2, 0.95 ],
            "decayType": "monod"
The widthPixels and heightPixels properties define the resolution of the virtual image the optimizer creates internally when it's evaluating transits. It helps if resolution is good, but optimizer run time is approximately linear on the number of pixels.

I defined orbitPeriod as 4 years, in days. That's just a guess, but as long as the transit time span is a small fraction of the orbital period, it doesn't really matter. The optimizer approximates transit motion linearly anyway.

Now, orbitRadius (expressed in stellar radii) should be consistent with the orbital period. It's just an approximation, but it helps if it's accurate. The optimizer will try to estimate the true orbit's radius, and it uses orbitRadiusFlexibility (a fraction of the radius) to establish parameter bounds. The orbitRadius I'm using here is the result of an initial estimate followed by analysis of trial runs with broader flexibility.

The method object specifies the transit type the optimizer will try to fit.  The object's type property is set to "code", meaning we will use a custom transit opacity function. Other values for type, which I will not be discussing in detail today, include "image" (lc-opt can fit an arbitrary grayscale image) and "neural" (a general purpose neural network that renders transits.)

The transit opacity function builder we will use is called "GradientRingPlanetBuilder". It represents a planet with a single ring that has an opacity gradient. There's also a "RingedPlanetBuilder", but that requires using at least one parameter per ring. The optimizer has an easier time with a single ring whose opacity varies in a certain way.

Bounds of GradientRingPlanetBuilder parameters are determined based on trial and error and what makes sense. 

The originX parameter of GradientRingPlanetBuilder determines where the center of the transit image (the planet) will be in the X axis relative to the star, in stellar radii, when the timestamp corresponds to the center of mass of the light curve. Because of D792's asymmetry, originX will be negative. Similarly, impactParameter could also be called originY.

Opacity decays outward starting at the inner ring's radius. It is half the maximum value at a distance equal to ringHalfOpacityRadius from the center of the planet. The type of decay function is given by decayType. In this case I'm using a Monod Function, which is something I already knew works well with D792.

The lc-opt tool can be run as follows (this is suitable for the Git Bash shell in Windows):
bin/lc-opt -log INFO -oinp 500000 -i examples/lc/kic8462852/D792.csv -o /c/path/to/result.csv -or /c/path/to/result.json -oi /c/path/to/result.png /path/to/optspec-d792-ring-planet.json
This will produce a transit model depiction PNG image, which looks like this:

The ring is extensive (pegged at the maximum of 20 stellar radii we allowed the optimizer) but most of it is very diffuse, so you can't really see it. The CSV file dumped by the tool gives us the light curve, which follows:

The visual fit is pretty good and RMSE is 0.0021, but the devil is in the details.

The planet's radius produced by the optimizer is 0.346 stellar radii, which is consistent with Ballesteros et al. (2017). That's big for a planet, but not unheard of. Our ring system, however, is at least twice as big as the one proposed by Ballesteros et al. and the optimizer apparently wants it to be even bigger. You can see how the modeled light curve gets cut off while Kepler's just keeps going:

You can try to force a smaller ring by manipulating the orbit's radius and so on, but you'll just get a poorer fit.

The tip of the light curve is also of interest.

There's an obvious artifact created by the gap between the planet and the ring. It can probably be salvaged by adding a ring closer to the planet that doesn't follow the opacity pattern of the rest of the ring system. Otherwise, the fit at the tip of the light curve is surprisingly good, even though the Kepler light curve does something that is a little odd.

There's a final point that is key. Would a real-world ring system behave like one with the clean opacity gradient we created? I took optimizer-produced parameters and created a 50-ring simulation (video here) with a similar opacity decay, in average, but where individual ring opacity has been randomly altered to make it more realistic. The following ingress curve can be compared to charts above.


A ringed planet fit of D792 is not terrible. There are some problems which might be salvageable in some way we haven't considered. In any case, the idea of tilting a disc/ring to produce an asymmetric transit light curve is of interest if we're to continue to pursue modeling the dips of Boyajian's star under the assumption they are produced by transits.


Ballesteros, et al. (2017). KIC 8462852: Will the Trojans return in 2021? arXiv:1705.08427