# Finding periodicity in discrete events II - missions to Mars

Per the Space Exploration SE question Are launch windows to Mars avoided if they result in landings during dust storm season? the synodic period of the relationship between the motion of Earth and Mars in their orbits with the approximation that they are circular and periodic is given by the following:

Launches to Mars happen each Earth-Mars synodic period:

$$T_{syn} = \frac{1}{\frac{1}{T_<} - \frac{1}{T_>}} = \frac{T_< T_>}{T_> - T_<}$$

With $$T_>, T_<$$ of 1.881 and 1.0 years that's about 2.14 years.

So about every 2.14 years there's an opportunity to launch with a local minimum of delta-v required.

I went to Wikipedia's List of missions to Mars and skipped the flybys to other bodies that only used Mars as a gravitational assist, and kept 45 that were destined for Mars.

So I have a list of 45 events in time, and I'd like to know the likelihood that there is an underlying periodicity $$T$$.

Below is the results of my Python script. I can verify a clustering both visually in the first 2D modulo plot, and by the peak in the "inter-arrival" time histogram from this answer to Finding periodicity in discrete events

But I'm basically just trying stuff here. Is there:

1. A formal way to do this kind of an analysis, with perhaps a well-defined likelihood or probability distribution for an underlying periodicity $$T$$?
2. Is there a nice python package that will do it?

Script:

info = """30 July 2020
23 July 2020
19 July 2020
5 May 2018
14 March 2016
18 November 2013
5 November 2013
26 November 2011
4 August 2007
12 August 2005
8 July 2003
10 June 2003
2 June 2003
7 April 2001
3 January 1999
11 December 1998
4 December 1996
16 November 1996
7 November 1996
25 September 1992
12 July 1988
7 July 1988
9 September 1975
20 August 1975
9 August 1973
5 August 1973
25 July 1973
21 July 1973
30 May 1971
28 May 1971
19 May 1971
10 May 1971
9 May 1971
2 April 1969
27 March 1969
27 March 1969
25 February 1969
30 November 1964
28 November 1964
5 November 1964
4 November 1962
1 November 1962
24 October 1962
14 October 1960
10 October 1960""" # https://en.wikipedia.org/wiki/List_of_missions_to_Mars

import numpy as np
import matplotlib.pyplot as plt
import calendar, datetime
# from scipy.signal import periodogram, lombscargle # no, not these

# https://stackoverflow.com/a/3418092/3904031
d = {month: index for index, month in enumerate(calendar.month_abbr) if month}

lines = info.splitlines()
dates = [line.split(' ') for line in lines]
dates = [(int(a), int(d[b[:3]]), int(c))[::-1] for a, b, c in dates]

datetimes = [datetime.datetime(*date) for date in dates]

seconds = np.array([datetime.timestamp() for datetime in datetimes])

years = seconds / (365.25 * 24 * 3600) # "Julian years"

plt.plot(years)
plt.show()

mods = np.linspace(0.5, 5, 251)
results = np.array([np.mod(years, mod) for mod in mods])

# inter-arrival times https://dsp.stackexchange.com/a/55971/25659
yearz = (years[:, None] - years).flatten()

if True:
fig, (ax1, ax2) = plt.subplots(2, 1)
for mod, dots in zip(mods, results):
ax1.plot(mod * np.ones_like(dots), dots, '.k', ms=1)
a, b = np.histogram(yearz, bins=mods)
ax2.plot(b[1:], a)
ax2.set_xlabel('modulo (years)')
plt.show()

– uhoh
Mar 22, 2023 at 22:24
• You could ask at CrossValidated in the "seasonality" tag. Much of that is about how to treat known seasonality in time series (if we have daily data, we often know there is a seasonal frequency of 7, i.e., intra-weekly seasonality), but there are a few threads about how to detect the length of seasonality, e.g., Automatic detection of seasonality on a time-series. I don't know whether the pointer in my answer would work in this case, though... Mar 23, 2023 at 7:57
• @StephanKolassa thanks! I posted a link in the main chat room there, but that's a good idea, thanks!
– uhoh
Mar 23, 2023 at 8:37
• ... and your chat post there is what brought me here, thank you for drawing our attention that way! Mar 23, 2023 at 8:46