Open In Colab

d8d683f4f010484bb8e072e52fcbbd01

Montunctions

In this notebook we calculate the conjunction between Mars and Aldebaran during the so-called stationary phases of the planet. This notebook and the derived plots were used in the context of the work “ESTUDIO DE LAS ORIENTACIONES ASTRONÓMICAS Y PAISAJÍSTICAS DE LOS MONUMENTOS DE SENENMUT EN LA NECRÓPOLIS TEBANA” presented as Ph. D. Thesis by Francisco Vivas Fernández (2023).

If you are running this script in Google Colab you need first to install the package and create a directory for saving plots:

[1]:
try:
    from google.colab import drive
    %pip install -Uq montu
except ImportError:
    print("Not running in Colab, skipping installation")
    import plotly.io as pio
    pio.renderers.default = "notebook_connected"
    %load_ext autoreload
    %autoreload 2
# Create folders for figures and temporal files
!mkdir -p ./gallery/ ./montu_dem/
Not running in Colab, skipping installation

Goals of this notebook

The goal of this notebook is to determine the stable positions of mars across ancient Egypt history and check when this marsticies happened close to the winter solstice and in the Taurus constellation.

Loading tools

We need to load the packages and the required data for it (star database, planet position database, etc.):

[2]:
# Montu packages and data
%matplotlib inline
import montu
from montu import D2S, PRINTDF, TABLEDF, DEG, RAD

# Other libraries required
import pandas as pd
import copy
import matplotlib.pyplot as plt
import numpy as np

# Load allstars
allstars = montu.Stars()


MontuPython version 0.50.0. 𓇍𓇋𓇋𓏏𓅓𓊵 𓎛𓎡𓄿𓀭𓎛𓈖𓂝𓎡 (ii-ti m Htp, HkAx Hn'-k)
Loading stellar catalogue montu_stellar_catalogue_v38.csv

Marstices

Lets set observing conditions and initial time of exploration:

[3]:
Tebas = montu.Observer(lon=33,lat=24,height=0)

Our target body:

[4]:
mars = montu.Planet('Mars')

Now let’s predict all the Marstices:

[5]:
marstices = pd.DataFrame()
i = 0

# Range of years
# initial_year = -2500
initial_year = -2000
final_year = -500

mars.reset_store()
mtime = montu.Time(f'{initial_year}-01-01 00:00:00.00',scale='utc',calendar='proleptic')

marstices = []
for _ in montu.WHILE_TRUE():
    jed1,jed2 = mars.next_planesticies(mtime)
    mtime1 = montu.Time(jed1,format='jd',full=True)
    mtime2 = montu.Time(jed2,format='jd',full=True)

    # Stopping condition
    if mtime2.readable.year > final_year:
        break

    marstices += [pd.DataFrame(dict(
        datepro = [mtime1.readable.datepro,mtime2.readable.datepro],
        datemix = [mtime1.readable.datemix,mtime2.readable.datemix],
        type = ['first','second'],
        jed = [mtime1.jed,mtime2.jed],
    ))]

    mtime = mtime + 2*montu.YEAR
    i += 1

marstices = pd.concat(marstices)
marstices.drop_duplicates(inplace=True)
marstices.reset_index(drop=True,inplace=True)
750it [00:00, 3932.12it/s]
[6]:
marstices
[6]:
datepro datemix type jed
0 -2001-09-21 12:52:37.202864 -2001-10-08 12:52:52 first 9.904730e+05
1 -2001-12-09 02:02:01.397744 -2001-12-26 02:02:02 second 9.905516e+05
2 -1999-10-25 10:48:04.207680 -1999-11-11 10:48:48 first 9.912380e+05
3 -1998-01-14 00:58:12.599040 -1998-01-31 00:58:58 second 9.913185e+05
4 -1997-11-30 04:28:27.698864 -1997-12-17 04:28:28 first 9.920037e+05
... ... ... ... ...
1401 -506-09-04 21:49:24.496304 -506-09-10 21:49:49 second 1.536494e+06
1402 -504-08-30 13:09:38.597744 -504-09-05 13:09:09 first 1.537220e+06
1403 -504-11-10 12:33:59.497920 -504-11-16 12:33:33 second 1.537292e+06
1404 -502-10-10 16:51:06.001920 -502-10-16 16:51:51 first 1.537991e+06
1405 -502-12-27 13:11:26.399040 -501-01-02 13:11:11 second 1.538069e+06

1406 rows × 4 columns

Now we want to add to this information other relevant astronomical information:

  1. Position of mars in the sky

  2. Date of occurrence of winter solstices

  3. Angular distance of Mars to Aldebaran

Position of Mars in the sky:

[7]:
mars.reset_store()
for index in montu.PROGRESS(marstices.index):
    marstice = marstices.loc[index]

    # Get MonTime object
    mtime = montu.Time(marstice.jed,format='jd')

    # Calculate Mars position and store it
    mars.conditions_in_sky(mtime,Tebas,store=1)
mars.tabulate_store()
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1406/1406 [00:00<00:00, 5083.95it/s]

Positions are stored in a separate dataframe:

[8]:
mars_marstices = copy.deepcopy(mars.position)
mars_marstices['Vmag'] = mars.condition.Vmag
mars_marstices
[8]:
tt jed Name RAJ2000 DecJ2000 RAEpoch DecEpoch RAGeo DecGeo el az Vmag
0 -126236570942 9.904730e+05 Mars 7.026757 23.322960 3.073795 17.836212 3.073797 17.838371 -48.159613 359.135417 -0.67
1 -126229784378 9.905516e+05 Mars 5.632474 26.221096 1.774031 13.756077 1.774203 13.757510 -15.035019 292.899084 -0.43
2 -126170482464 9.912380e+05 Mars 9.479705 17.711436 5.517021 26.057501 5.517134 26.059545 -29.869770 324.116464 -0.39
3 -126163519480 9.913185e+05 Mars 8.165966 24.253872 4.077912 24.892369 4.078105 24.893611 2.560390 296.310081 -0.35
4 -126104322889 9.920037e+05 Mars 11.642726 6.391030 8.006254 24.704358 8.006401 24.704688 46.465886 281.282326 -0.40
... ... ... ... ... ... ... ... ... ... ... ... ...
1401 -79060353742 1.536494e+06 Mars 23.006199 -11.674151 20.715271 -23.418157 20.715457 -23.414697 32.736253 216.581241 -1.98
1402 -78997658558 1.537220e+06 Mars 3.772105 17.271194 1.514450 6.586747 1.514421 6.588904 -58.778088 12.376669 -1.44
1403 -78991439897 1.537292e+06 Mars 2.614838 15.741818 0.423314 2.972830 0.423091 2.974326 -2.157872 85.168320 -1.02
1404 -78931030900 1.537991e+06 Mars 6.919953 23.751538 4.395169 22.487648 4.394980 22.489512 -16.465913 55.376534 -0.76
1405 -78924304895 1.538069e+06 Mars 5.538215 26.342942 3.047465 20.323564 3.047270 20.324541 17.519819 75.021603 -0.49

1406 rows × 12 columns

Compute the date of the previous and next winter solstice, and the days elapsed to the closest one:

[9]:
# Loop on marstices
for index in montu.PROGRESS(marstices.index):
    marstice = marstices.loc[index]

    # Get MonTime object
    mtime = montu.Time(marstice.jed,format='jd')

    # Calculate next and previous solstices
    prev_seasons = montu.Sun.previous_seasons(at=mtime)
    next_seasons = montu.Sun.next_seasons(at=mtime)

    # Get the closest solstice
    closest_solstice = min(abs(mtime.jed - prev_seasons[3]),
                           abs(mtime.jed - next_seasons[3]))

    # Add winter solstice to DataFrame
    marstices.loc[index,'closest_solstice'] = closest_solstice

marstices
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1406/1406 [00:00<00:00, 3048.48it/s]
[9]:
datepro datemix type jed closest_solstice
0 -2001-09-21 12:52:37.202864 -2001-10-08 12:52:52 first 9.904730e+05 89.858280
1 -2001-12-09 02:02:01.397744 -2001-12-26 02:02:02 second 9.905516e+05 11.310084
2 -1999-10-25 10:48:04.207680 -1999-11-11 10:48:48 first 9.912380e+05 55.435827
3 -1998-01-14 00:58:12.599040 -1998-01-31 00:58:58 second 9.913185e+05 25.154548
4 -1997-11-30 04:28:27.698864 -1997-12-17 04:28:28 first 9.920037e+05 20.186209
... ... ... ... ... ...
1401 -506-09-04 21:49:24.496304 -506-09-10 21:49:49 second 1.536494e+06 106.888026
1402 -504-08-30 13:09:38.597744 -504-09-05 13:09:09 first 1.537220e+06 111.737487
1403 -504-11-10 12:33:59.497920 -504-11-16 12:33:33 second 1.537292e+06 39.762245
1404 -502-10-10 16:51:06.001920 -502-10-16 16:51:51 first 1.537991e+06 71.062716
1405 -502-12-27 13:11:26.399040 -501-01-02 13:11:11 second 1.538069e+06 6.784743

1406 rows × 5 columns

[10]:
marstices.iloc[:10]
[10]:
datepro datemix type jed closest_solstice
0 -2001-09-21 12:52:37.202864 -2001-10-08 12:52:52 first 990473.036542 89.858280
1 -2001-12-09 02:02:01.397744 -2001-12-26 02:02:02 second 990551.584738 11.310084
2 -1999-10-25 10:48:04.207680 -1999-11-11 10:48:48 first 991237.950049 55.435827
3 -1998-01-14 00:58:12.599040 -1998-01-31 00:58:58 second 991318.540424 25.154548
4 -1997-11-30 04:28:27.698864 -1997-12-17 04:28:28 first 992003.686432 20.186209
5 -1996-02-18 07:27:10.992944 -1996-03-06 07:27:27 second 992083.810544 59.937904
6 -1994-01-10 01:13:45.304320 -1994-01-27 01:13:13 first 992775.551219 21.198671
7 -1994-03-27 17:44:02.307824 -1994-04-13 17:44:44 second 992852.238916 97.886368
8 -1992-03-07 22:03:49.904640 -1992-03-24 22:03:03 first 993563.419328 78.589665
9 -1992-05-14 16:51:47.404800 -1992-05-31 16:51:51 second 993631.202632 146.372970

Now we want to compute the angular distance to Aldebaran. For this purpose, we need to get the information about the star from the database:

[11]:
aldebaran = allstars.get_stars(ProperName='Aldebaran')
aldebaran
[11]:
1 star(s):
|    |   MN |    HD |   HR |   HIP | Gl        | Name      | OtherDesignations                                                                     | ProperName   | Bayer   | Flamsteed   | Constellation   |   RAJ2000 |   DecJ2000 |   GalLonJ2000 |   GalLatJ2000 |   pmRA |   pmDec |   RadVel |   Distance |   Vmag |   Vmag_min |   Vmag_max |   B-V | SpType   |   Luminosity |   XJ2000 |   YJ2000 |   ZJ2000 |   VXJ2000 |   VYJ2000 |   VZJ2000 |   Primary | MultipleID   |   IsMultiple |   IsVariable |
|----|------|-------|------|-------|-----------|-----------|---------------------------------------------------------------------------------------|--------------|---------|-------------|-----------------|-----------|------------|---------------|---------------|--------|---------|----------|------------|--------|------------|------------|-------|----------|--------------|----------|----------|----------|-----------|-----------|-----------|-----------|--------------|--------------|--------------|
| 14 |   15 | 29139 | 1457 | 21421 | Gl 171.1A | Aldebaran | 87 Tau/87Alp Tau/Aldebaran/Gl 171.1A/HD 29139/HIP 21421/HR 1457/HYG 21368/MN 15/α Tau | Aldebaran    | α Tau   | 87 Tau      | Tau             |   4.59868 |    16.5093 |       180.972 |      -20.2483 |  62.78 | -189.36 |     54.5 |    20.4332 |   0.87 |      0.888 |      0.858 | 1.538 | K5III    |       163.23 |  7.02722 |  18.2876 |  5.80666 | 1.528e-05 | 5.709e-05 | -2.14e-06 |     21368 | Gl 171.1     |            1 |            1 |

Now we will compute for each marstice, the angular distance to Aldebaran:

[12]:
# Loop on marstices
for index in montu.PROGRESS(marstices.index):

    # Get marstice information and location of mars
    marstice = marstices.loc[index]
    mars_location = mars_marstices.loc[index]

    # Propagate aldebaran to epoch
    mtime = montu.Time(marstice.jed,format='jd')
    aldebaran.where_in_space(at=mtime,inplace=True)

    # Compute angular distance
    aldebaran_angdist = montu.Util.haversine_distance(
        mars_location.DecJ2000*DEG,15*mars_location.RAJ2000*DEG,
        aldebaran.scalar('DecJ2000t')*DEG,15*aldebaran.scalar('RAJ2000t')*DEG
    )*RAD

    # uncomment to check
    """
    print(marstice.jed,marstice.datemix)
    print(D2S(mars_location.DecJ2000),D2S(mars_location.RAJ2000))
    print(D2S(aldebaran.scalar('DecJ2000t')),D2S(aldebaran.scalar('RAJ2000t')))
    print(D2S(aldebaran_angdist))
    break
    #"""

    # Angular distance
    marstices.loc[index,'aldebaran_angdist'] = aldebaran_angdist

marstices
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1406/1406 [00:00<00:00, 1988.75it/s]
[12]:
datepro datemix type jed closest_solstice aldebaran_angdist
0 -2001-09-21 12:52:37.202864 -2001-10-08 12:52:52 first 9.904730e+05 89.858280 34.820239
1 -2001-12-09 02:02:01.397744 -2001-12-26 02:02:02 second 9.905516e+05 11.310084 17.306733
2 -1999-10-25 10:48:04.207680 -1999-11-11 10:48:48 first 9.912380e+05 55.435827 69.517868
3 -1998-01-14 00:58:12.599040 -1998-01-31 00:58:58 second 9.913185e+05 25.154548 50.461178
4 -1997-11-30 04:28:27.698864 -1997-12-17 04:28:28 first 9.920037e+05 20.186209 103.062474
... ... ... ... ... ... ...
1401 -506-09-04 21:49:24.496304 -506-09-10 21:49:49 second 1.536494e+06 106.888026 87.553815
1402 -504-08-30 13:09:38.597744 -504-09-05 13:09:09 first 1.537220e+06 111.737487 11.832605
1403 -504-11-10 12:33:59.497920 -504-11-16 12:33:33 second 1.537292e+06 39.762245 28.523663
1404 -502-10-10 16:51:06.001920 -502-10-16 16:51:51 first 1.537991e+06 71.062716 33.393108
1405 -502-12-27 13:11:26.399040 -501-01-02 13:11:11 second 1.538069e+06 6.784743 16.322561

1406 rows × 6 columns

[13]:
marstices.aldebaran_angdist.describe()
[13]:
count    1406.000000
mean       84.160880
std        50.362013
min         3.311582
25%        39.914786
50%        81.051776
75%       126.587916
max       176.560331
Name: aldebaran_angdist, dtype: float64

Now we will mark the marstices according to closest solstice and aldebaran angular distance:

[14]:
max_days_to_solstice = 15 # days
max_aldebaran_angdist = 15 # degrees
max_aldebaran_conjunc = 5 # degrees

marstices['close_solstice'] = False
marstices['close_aldebaran'] = False
marstices['conj_aldebaran'] = False
marstices['montunctions'] = False

cond_solstices = (marstices['closest_solstice']<=max_days_to_solstice)
marstices.loc[cond_solstices,'close_solstice'] = True
print("Number of marstices close to solstices: ",cond_solstices.sum())

cond_aldebaran = (marstices['aldebaran_angdist']<=max_aldebaran_angdist)
marstices.loc[cond_aldebaran,'close_aldebaran'] = True
print("Number of marstices close to Aldebaran: ",cond_aldebaran.sum())

cond_montunctions = (cond_solstices) & (cond_aldebaran)
marstices.loc[cond_montunctions,'montunctions'] = True
print("Number of Montunctions: ",cond_montunctions.sum())

cond_conjunction = (marstices['aldebaran_angdist']<=max_aldebaran_conjunc)
marstices.loc[cond_conjunction,'conj_aldebaran'] = True
print("Number of close conjunctions: ",cond_conjunction.sum())
Number of marstices close to solstices:  146
Number of marstices close to Aldebaran:  121
Number of Montunctions:  24
Number of close conjunctions:  15

These are the dates:

[15]:
mtime_start = montu.Time('bce1050-01-01 00:00:00.00')+(-10*montu.YEAR)
mtime_end = montu.Time('bce1050-01-01 00:00:00.00')+10*montu.YEAR
cond = (marstices.jed>=mtime_start.jed) & (marstices.jed<=mtime_end.jed)
marstices[cond]
[15]:
datepro datemix type jed closest_solstice aldebaran_angdist close_solstice close_aldebaran conj_aldebaran montunctions
882 -1059-06-03 00:48:55.802880 -1059-06-13 00:48:48 first 1.334422e+06 164.897449 101.821584 False False False False
883 -1059-08-02 10:56:53.096656 -1059-08-12 10:56:56 second 1.334482e+06 139.920916 111.666625 False False False False
884 -1057-08-07 06:00:19.500480 -1057-08-17 06:00:00 first 1.335217e+06 135.620189 29.896782 False False False False
885 -1057-10-15 18:54:00.596160 -1057-10-25 18:54:54 second 1.335286e+06 66.082908 45.237112 False False False False
886 -1055-09-19 17:26:40.695360 -1055-09-29 17:26:26 first 1.335991e+06 91.629515 19.539714 False False False False
887 -1055-12-05 05:15:46.794240 -1055-12-15 05:15:15 second 1.336068e+06 15.137084 7.563516 False True False False
888 -1053-10-26 01:12:23.595824 -1053-11-05 01:12:12 first 1.336758e+06 55.790945 56.637174 False False False False
889 -1052-01-13 21:06:54.097920 -1052-01-23 21:06:06 second 1.336837e+06 24.038575 37.863884 False False False False
890 -1051-11-28 14:37:33.896640 -1051-12-08 14:37:37 first 1.337522e+06 21.721740 90.114387 False False False False
891 -1050-02-17 08:54:18.201600 -1050-02-27 08:54:54 second 1.337603e+06 59.039884 70.931521 False False False False
892 -1048-01-05 10:51:15.998416 -1048-01-15 10:51:51 first 1.338290e+06 15.631285 124.671995 False False False False
893 -1048-03-24 13:37:48.797760 -1048-04-03 13:37:37 second 1.338369e+06 94.746943 106.237353 False False False False
894 -1046-02-21 15:09:06.497280 -1046-03-03 15:09:09 first 1.339068e+06 63.329107 165.916162 False False False False
895 -1046-05-05 21:09:13.201936 -1046-05-15 21:09:09 second 1.339141e+06 136.579185 149.931005 False False False False
896 -1044-05-01 23:08:53.802240 -1044-05-11 23:08:08 first 1.339868e+06 133.184542 132.748457 False False False False
897 -1044-07-02 22:14:13.202880 -1044-07-12 22:14:14 second 1.339930e+06 170.098364 142.427358 False False False False
898 -1042-07-16 09:04:26.302080 -1042-07-26 09:04:04 first 1.340674e+06 157.130109 55.004732 False False False False
899 -1042-09-19 15:45:53.507520 -1042-09-29 15:45:45 second 1.340739e+06 91.851322 68.038361 False False False False
900 -1040-09-03 21:59:01.104000 -1040-09-13 21:59:59 first 1.341454e+06 107.078913 4.128862 False True True False
901 -1040-11-17 02:44:51.806400 -1040-11-27 02:44:44 second 1.341529e+06 32.880409 16.925303 False False False False

Periodicity of marstices and montunctions

Now we want to calculate the periodicities of Marstices and Montunctions by calculating the difference in time between consecutive phenomena.

Setting parameters for winter marstices, aldebaran conjunctions and montunctions

[16]:
max_days_to_solstice = 15 # days
max_aldebaran_angdist = 15 # degrees

marstices['close_solstice'] = False
marstices['close_aldebaran'] = False
marstices['conj_aldebaran'] = False
marstices['montunctions'] = False

cond_solstices = (marstices['closest_solstice']<=max_days_to_solstice)
marstices.loc[cond_solstices,'close_solstice'] = True
print("Number of marstices close to solstices: ",cond_solstices.sum())

cond_aldebaran = (marstices['aldebaran_angdist']<=max_aldebaran_angdist)
marstices.loc[cond_aldebaran,'close_aldebaran'] = True
print("Number of marstices close to Aldebaran: ",cond_aldebaran.sum())

cond_montunctions = (cond_solstices) & (cond_aldebaran)
marstices.loc[cond_montunctions,'montunctions'] = True
print("Number of Montunctions: ",cond_montunctions.sum())

cond_conjunction = (marstices['aldebaran_angdist']<=max_aldebaran_conjunc)
marstices.loc[cond_conjunction,'conj_aldebaran'] = True
print("Number of close conjunctions: ",cond_conjunction.sum())

montunctions = marstices.loc[marstices.montunctions]
Number of marstices close to solstices:  146
Number of marstices close to Aldebaran:  121
Number of Montunctions:  24
Number of close conjunctions:  15

Periodicity of marstices

[17]:
times = marstices.jed.to_numpy()
delta1 = times[2::2]-times[:-2:2]
delta2 = times[1::2]-times[:-1:2]

Histogram of times:

[18]:
fig,axs = plt.subplots(1,2,figsize=(10,5),sharey=True)

ax = axs[0]
hs1 = ax.hist(delta1,bins=50)
ax.set_xlabel("Time [day]")
ax.set_ylabel("Number of pair of marstices")
ax.set_title("Difference between synodic marstices")
ax.grid()

ax = axs[1]
hs2 = ax.hist(delta2,bins=50)
ax.set_title("Difference between consecutive marstices")
ax.set_xlabel("Time [day]")
ax.grid()

fig.tight_layout()

../_images/examples_MontuPython-Montunctions_42_0.png
../_images/examples_MontuPython-Montunctions_42_1.png
[19]:
print(f"Periodicity of synodic marstices: {hs1[1][0]:.1f} - {hs1[1][-1]:.1f}")
print(f"Periodicity of consecutive marstices: {hs2[1][0]:.1f} - {hs2[1][-1]:.1f}")

Periodicity of synodic marstices: 764.5 - 809.9
Periodicity of consecutive marstices: 60.3 - 80.9

Periodicity of winter marstices

Let’s extract the winter marstices:

[20]:
winter_marstices = marstices[marstices.close_solstice]

Let’s get the periodicity:

[21]:
times = winter_marstices.jed.to_numpy()
delta = (times[1:]-times[:-1])*montu.DAY/montu.YEAR
hs = plt.hist(delta,bins=200)
plt.show()

../_images/examples_MontuPython-Montunctions_48_0.png

Get the periodicities:

[22]:
# Times
ts = (hs[1][1:]+hs[1][:-1])/2
# Frequencies
fs = hs[0]
# Times with a positive frequency
cond = fs>0
isort = fs[cond].argsort()[::-1]
Ps = ts[cond][isort]
print("Periods of winter marstices [years]: ", Ps)
Periods of winter marstices [years]:  [11.0162576   4.03507962 17.03451448 21.00656402 27.98774199]

Periodicity of Aldebaran conjunctions

Let’s extract the Aldebaran conjunctions:

[23]:
aldebaran_marstices = marstices[marstices.close_aldebaran]
len(aldebaran_marstices)
[23]:
121

Let’s get the periodicity:

[24]:
times = aldebaran_marstices.jed.to_numpy()
delta = (times[1:]-times[:-1])*montu.DAY/montu.YEAR
hs = plt.hist(delta,bins=100)
plt.show()

../_images/examples_MontuPython-Montunctions_55_0.png

Get the periodicities:

[25]:
# Times
ts = (hs[1][1:]+hs[1][:-1])/2
# Frequencies
fs = hs[0]
# Times with a positive frequency
cond = fs>0
isort = fs[cond].argsort()[::-1]
Ps = ts[cond][isort]
print("Periods of winter marstices [years]: ", Ps)
Periods of winter marstices [years]:  [14.80330875 17.19389575  0.28903055 14.97406496  2.33810512]

Periodicity of Montunctions

Let’s extract the Aldebaran conjunctions:

[26]:
len(montunctions)
[26]:
24

Let’s get the periodicity:

[27]:
times = montunctions.jed.to_numpy()
delta = (times[1:]-times[:-1])*montu.DAY/montu.YEAR
hs = plt.hist(delta,bins=100)
plt.xlabel("Period [years]")
plt.ylabel("Number of Montunctions")
plt.show()

../_images/examples_MontuPython-Montunctions_62_0.png

Get the periodicities:

[28]:
# Times
ts = (hs[1][1:]+hs[1][:-1])/2
# Frequencies
fs = hs[0]
# Times with a positive frequency
cond = fs>0
isort = fs[cond].argsort()[::-1]
Ps = ts[cond][isort]
print("Periods of Montunctions [years]: ", Ps)
Periods of Montunctions [years]:  [ 46.31123293  78.61829458  31.1079098  204.04571042  15.90458667]

Lines chart of marstices and montunctions

[29]:
# Selection of marstices
selection = marstices.loc[:]
nmarstices = len(selection)

jed_min = (1-1e-3)*selection.jed.min()
jed_max = (1+1e-3)*selection.jed.max()

# Number of panels
npanels = 6
delta_jed = (jed_max - jed_min)/npanels
[30]:
import datetime
[31]:
fig,axs = plt.subplots(npanels,1,figsize=(12,10))

axts = []
for ax in axs:
    axts += [ax.twinx()]

alpha_marst = 0.05
alpha_wmarst = 0.3
alpha_aldeb = 0.3
alpha_montu = 1
alpha_mag = 0.3

# Loop on marstices
for index in selection.index:

    # Get marstice information and location of mars
    marstice = selection.loc[index]
    mars_location = mars_marstices.loc[index]

    # Get MonTime object
    mtime = montu.Time(marstice.jed,format='jd')

    # Get panel
    i = int(np.floor((mtime.jed - jed_min)/delta_jed))

    # Plot line for marstices
    axs[i].axvline(mtime.jed,color='k',alpha=alpha_marst)

    # Plot line for winter marstices
    if marstice.close_solstice:
        axs[i].axvline(mtime.jed,color='b',lw=2,alpha=alpha_wmarst)

    # Plot line for aldebaran conjunctions
    if marstice.close_aldebaran:
        axs[i].axvline(mtime.jed,color='r',lw=2,alpha=alpha_aldeb)

    # Plot line for aldebaran close conjunctions
    if marstice.conj_aldebaran:
        axs[i].axvline(mtime.jed,color='g',lw=5,alpha=alpha_montu)

    # Plot line for montunctions
    if marstice.close_solstice and marstice.close_aldebaran:
        axs[i].axvline(mtime.jed,color='k',lw=5,alpha=alpha_montu)

# Plot distance
for i,axt in enumerate(axts):
    jed_ax_min = jed_min + i*delta_jed
    jed_ax_max = jed_ax_min + delta_jed
    cond = (marstices.jed>=jed_ax_min)&(marstices.jed<=jed_ax_max)
    #axt.plot(marstices[cond].jed,mars.df[cond].site_distance,'k',alpha=0.4)
    axt.plot(marstices[cond].jed,mars_marstices[cond].Vmag,'k--',alpha=0.4)

# Loop on marstices
for index in selection.index:
    # Get MonTime object
    mtime = montu.Time(marstice.jed,format='jd')

    # Get marstice information and location of mars
    marstice = selection.loc[index]

    # Get panel
    i = int(np.floor((mtime.jed - jed_min)/delta_jed))

    # Plot line for aldebaran close conjunctions
    if marstice.conj_aldebaran:
        mmin,mmax = axts[i].get_ylim()
        t = axts[i].text(mtime.jed,0.95*mmax,f"a.d.{marstice.aldebaran_angdist:.1f}",
                         ha='center',va='center',fontsize=8)

# Decoration
for i,ax in enumerate(axs):
    ax.margins(0)
    ax.get_yaxis().set_visible(False)
    jed_ax_min = jed_min + i*delta_jed
    jed_ax_max = jed_ax_min + delta_jed
    ax.set_xticks(np.linspace(jed_ax_min,jed_ax_max,10))

# Change xticks
for ax in axs:
    xticks = ax.get_xticks()
    xtick_labels = []
    for xt in xticks:
        mtime = montu.Time(xt,format='jd',full=True)
        xtick_labels += [f'{mtime.readable.year}']
    ax.set_xticklabels(xtick_labels)

for ax in axts:
    ax.margins(0)
    ax.set_yticks(np.arange(-2.5,0.0,0.5))
    ax.get_yaxis().set_visible(False)

# Legends
axs[0].plot([],[],'k-',alpha=alpha_marst,label='Regular marstices')
axs[0].plot([],[],'b-',alpha=alpha_wmarst,label='Winter marstices')
axs[0].plot([],[],'r-',alpha=alpha_aldeb,label='Taurus marstices')
axs[0].plot([],[],'k-',alpha=alpha_montu,lw=3,label='Montunctions')
axs[0].plot([],[],'g-',alpha=alpha_montu,lw=3,label='Aldebaran conjunctions')
axs[0].plot([],[],'k--',alpha=alpha_mag,label='Mars magnitude')
axs[0].legend(bbox_to_anchor=(0.5,1.4),ncol=6,fontsize=9,loc='upper center')

# Other decoration
axs[-1].set_xlabel('Year')

axs[0].text(0.5,1.5,f"Marstices ({len(marstices)}), Aldebaran Conjunctions ({selection.conj_aldebaran.sum()}) and Montunctions ({len(montunctions)}) in Ancient Egypt",
            transform=axs[0].transAxes,fontsize=17,ha='center')

"""
# Spans
# Montuhotep II
iax = 1
j1 = montu.Time('-2066-01-01').jed
j2 = montu.Time('-1957-01-01').jed
jk = (j1+j2)/2
mmin,mmax = axs[iax].get_ylim()
axs[iax].axvspan(j1,j2,color='k',alpha=0.2)
t = axs[iax].text(jk,0.0,'Montuhotep II',ha='center',va='center',fontsize=10)
t.set_bbox(dict(facecolor='white', edgecolor='white'))
"""

# Senenmut
iax = 2
j1 = montu.Time('-1480-01-01').jed
j2 = montu.Time('-1458-01-01').jed
jmin,jmax = axs[iax].get_xlim()
j1 = max(j1,jmin)
j2 = min(j2,jmax)
jk = (j1+j2)/2
mmin,mmax = axs[iax].get_ylim()
axs[iax].axvspan(j1,j2,color='k',alpha=0.2)
t = axs[iax].text(jk,0.0,'Senenmut',ha='center',va='center',fontsize=10)
t.set_bbox(dict(facecolor='white', edgecolor='white'))

# Mentuemhat
iax = 5
j1 = montu.Time('-700-01-01').jed
j2 = montu.Time('-650-01-01').jed
jk = (j1+j2)/2
mmin,mmax = axs[iax].get_ylim()
axs[iax].axvspan(j1,j2,color='k',alpha=0.2)
t = axs[iax].text(jk,0.0,'Mentuemhat',ha='center',va='center',fontsize=10)
t.set_bbox(dict(facecolor='white', edgecolor='white'))

fig.tight_layout()

../_images/examples_MontuPython-Montunctions_68_0.png
../_images/examples_MontuPython-Montunctions_68_1.png

Magnitude at Montunctions:

[32]:
cond = cond_montunctions = (cond_solstices) & (cond_aldebaran)
hs = plt.hist(mars_marstices[cond].Vmag,color='r',alpha=0.3,
              weights=[1/len(mars_marstices[cond])]*len(mars_marstices[cond]))
hs = plt.hist(mars_marstices.Vmag,color='b',alpha=0.3,
              weights=[1/len(mars_marstices)]*len(mars_marstices))
plt.show()

../_images/examples_MontuPython-Montunctions_70_0.png

Montunctions visualization

Let’s see one of this montunctions in the sky:

[33]:
# Time of montunction
mtime_montunction = montu.Time(montunctions.iloc[-5].jed,format='jd',full=True)
t = mtime_montunction.tt

mars.reset_store()
for t in np.linspace(-50*montu.DAY,0*montu.DAY,50):
    # Get MonTime object
    mtime = mtime_montunction + t

    # Calculate Mars position and store it
    mars.where_in_sky(mtime,Tebas,store=1)
mars.tabulate_store()

Create a map of montunction:

[34]:
# Plot Hyades
hyades = allstars.get_stars_around(center=[aldebaran.data.RAJ2000,aldebaran.data.DecJ2000],radius=10,Vmag=[-1,5])
fig,ax = hyades.plot_stars(pad=0.0,labels=True,figargs=dict(figsize=(8,8)))

for index in mars.position.index:
    mars_position = mars.position.loc[index]
    ax.plot(15*mars_position.RAJ2000,mars_position.DecJ2000,'ro',ms=10,alpha=0.3)

ax.set_title(f"Mars Montunction at {mtime_montunction.readable.datespice}",fontsize=14)
montu.Util.montu_mark(ax);

../_images/examples_MontuPython-Montunctions_75_0.png
../_images/examples_MontuPython-Montunctions_75_1.png

Interesting montunctions

We are interested in the Montunctions happening around the date of birth or dead of Senenmut who, according to several chronologies lived between 1480bce and 1458 bce. Let’s select the montunctions in this range:

[35]:
mtime_start = montu.Time('bce1480-01-01 00:00:00.00')+(-50*montu.YEAR)
mtime_end = montu.Time('bce1480-01-01 00:00:00.00')+50*montu.YEAR

cond = (montunctions.jed>=mtime_start.jed) & (montunctions.jed<=mtime_end.jed)
print("Number of montunctions in the desired interval: ",cond.sum())

montunctions_selected = montunctions.loc[cond]
montunctions_selected
Number of montunctions in the desired interval:  2
[35]:
datepro datemix type jed closest_solstice aldebaran_angdist close_solstice close_aldebaran conj_aldebaran montunctions
459 -1512-12-10 23:40:17.296304 -1512-12-24 23:40:40 second 1.169158e+06 8.282254 14.651087 True True False True
503 -1465-12-06 03:30:47.802240 -1465-12-19 03:30:30 second 1.186319e+06 14.549713 9.723496 True True False True

Let’s see the montunctions:

[36]:
# Time of montunction
isel = 1
mtime_montunction = montu.Time(montunctions_selected.iloc[isel].jed,format='jd',full=True)
t = mtime_montunction.tt

mars.reset_store()
for t in np.linspace(-20*montu.DAY,20*montu.DAY,20):
    # Get MonTime object
    mtime = mtime_montunction + t

    # Calculate Mars position and store it
    mars.where_in_sky(mtime,Tebas,store=1)
mars.tabulate_store()

# Plot Hyades
hyades = allstars.get_stars_around(center=[aldebaran.data.RAJ2000,aldebaran.data.DecJ2000],radius=15,Vmag=[-1,5])
fig,ax = hyades.plot_stars(pad=0.0,labels=True,label_mag=4,figargs=dict(figsize=(8,8)))

for index in mars.position.index:
    mars_position = mars.position.loc[index]
    ax.plot(15*mars_position.RAJ2000,mars_position.DecJ2000,'ro',ms=10,alpha=0.3)

ax.set_title(f"Mars montunction at {-mtime_montunction.readable.year+1} \
b.c.e. {mtime_montunction.readable.month:02d}-{mtime_montunction.readable.day:02d} (Senenmut)",fontsize=13)
montu.Util.montu_mark(ax);

../_images/examples_MontuPython-Montunctions_80_0.png
../_images/examples_MontuPython-Montunctions_80_1.png

We are interested in the Montunctions happening around the date of birth or dead of Mentuhotep (2119 - 2103)

[37]:
mtime_start = montu.Time('bce600-01-01 00:00:00.00')+(-70*montu.YEAR)
mtime_end = montu.Time('bce600-01-01 00:00:00.00')+70*montu.YEAR

cond = (montunctions.jed>=mtime_start.jed) & (montunctions.jed<=mtime_end.jed)
print("Number of montunctions in the desired interval: ",cond.sum())

montunctions_selected = montunctions.loc[cond]
montunctions_selected
Number of montunctions in the desired interval:  5
[37]:
datepro datemix type jed closest_solstice aldebaran_angdist close_solstice close_aldebaran conj_aldebaran montunctions
1257 -660-12-20 23:18:09.103680 -660-12-27 23:18:18 second 1.480354e+06 0.604677 13.079182 True True False True
1301 -613-12-14 20:15:27.293760 -613-12-21 20:15:15 second 1.497514e+06 5.938564 8.667736 True True False True
1331 -581-12-25 06:26:22.200016 -581-12-31 06:26:26 second 1.509212e+06 3.708349 14.680452 True True False True
1345 -566-12-08 08:31:32.096640 -566-12-14 08:31:31 second 1.514674e+06 12.862503 8.097878 True True False True
1375 -534-12-18 05:15:19.604160 -534-12-24 05:15:15 second 1.526372e+06 2.773414 9.781388 True True False True
[38]:
# Time of montunction
isel = 0
mtime_montunction = montu.Time(montunctions_selected.iloc[isel].jed,format='jd',full=True)
t = mtime_montunction.tt

mars.reset_store()
for t in np.linspace(-20*montu.DAY,20*montu.DAY,20):
    # Get MonTime object
    mtime = mtime_montunction + t

    # Calculate Mars position and store it
    mars.where_in_sky(mtime,Tebas,store=1)
mars.tabulate_store()

# Plot Hyades
hyades = allstars.get_stars_around(center=[aldebaran.data.RAJ2000,aldebaran.data.DecJ2000],radius=15,Vmag=[-1,5])
fig,ax = hyades.plot_stars(pad=0.0,labels=True,label_mag=4,figargs=dict(figsize=(8,8)))

for index in mars.position.index:
    mars_position = mars.position.loc[index]
    ax.plot(15*mars_position.RAJ2000,mars_position.DecJ2000,'ro',ms=10,alpha=0.3)

ax.set_title(f"Mars montunction at {-mtime_montunction.readable.year+1} \
b.c.e. {mtime_montunction.readable.month:02d}-{mtime_montunction.readable.day:02d} (Mentuemhat)",fontsize=13)
montu.Util.montu_mark(ax);

../_images/examples_MontuPython-Montunctions_83_0.png
../_images/examples_MontuPython-Montunctions_83_1.png

Conjunctions

We are interested in the Montunctions happening around the date of birth or dead of Mentuhotep (2119 - 2103)

[39]:
mtime_start = montu.Time('bce1050-08-01 00:00:00.00')+(-1*montu.YEAR)
mtime_end = montu.Time('bce1050-08-01 00:00:00.00')+1*montu.YEAR

cond = (marstices.jed>=mtime_start.jed) & (marstices.jed<=mtime_end.jed)
print("Number of marstices in the desired interval: ",cond.sum())

marstices_selected = marstices.loc[cond]
marstices_selected
Number of marstices in the desired interval:  2
[39]:
datepro datemix type jed closest_solstice aldebaran_angdist close_solstice close_aldebaran conj_aldebaran montunctions
892 -1048-01-05 10:51:15.998416 -1048-01-15 10:51:51 first 1.338290e+06 15.631285 124.671995 False False False False
893 -1048-03-24 13:37:48.797760 -1048-04-03 13:37:37 second 1.338369e+06 94.746943 106.237353 False False False False
[40]:
# Time of montunction
isel = 0
mtime_marstice = montu.Time(marstices_selected.iloc[isel].jed,format='jd',full=True)
t = mtime_marstice.tt

mars.reset_store()
for t in np.linspace(-20*montu.DAY,20*montu.DAY,50):
    # Get MonTime object
    mtime = mtime_marstice + t

    # Calculate Mars position and store it
    mars.where_in_sky(mtime,Tebas,store=1)
mars.tabulate_store()

# Plot Hyades
hyades = allstars.get_stars_around(center=[aldebaran.data.RAJ2000,aldebaran.data.DecJ2000],radius=15,Vmag=[-1,5])
fig,ax = hyades.plot_stars(pad=0.0,labels=True,label_mag=4,figargs=dict(figsize=(8,8)))

for index in mars.position.index:
    mars_position = mars.position.loc[index]
    ax.plot(15*mars_position.RAJ2000,mars_position.DecJ2000,'ro',ms=10,alpha=0.3)

ax.set_title(f"Aldebaran conjunction during marstice at {-mtime_marstice.readable.year+1} \
b.c.e. {mtime_marstice.readable.month:02d}-{mtime_marstice.readable.day:02d} (Montuhotep II)",fontsize=13)
montu.Util.montu_mark(ax);

../_images/examples_MontuPython-Montunctions_87_0.png
../_images/examples_MontuPython-Montunctions_87_1.png
[41]:
mtime_start = montu.Time('bce1580-08-01 00:00:00.00')+(-100*montu.YEAR)
mtime_end = montu.Time('bce1580-08-01 00:00:00.00')+100*montu.YEAR

cond = (marstices.jed>=mtime_start.jed) & (marstices.jed<=mtime_end.jed) & (marstices.aldebaran_angdist<=max_aldebaran_conjunc)
print("Number of marstices in the desired interval: ",cond.sum())

marstices_selected = marstices.loc[cond]
marstices_selected
Number of marstices in the desired interval:  2
[41]:
datepro datemix type jed closest_solstice aldebaran_angdist close_solstice close_aldebaran conj_aldebaran montunctions
412 -1561-08-22 22:36:39.098880 -1561-09-05 22:36:36 first 1.151150e+06 119.410078 4.893175 False True True False
486 -1482-08-26 07:38:10.302720 -1482-09-08 07:38:38 first 1.180008e+06 116.239785 3.616589 False True True False
[42]:
# Time of montunction
isel = 1
mtime_marstice = montu.Time(marstices_selected.iloc[isel].jed,format='jd',full=True)
t = mtime_marstice.tt

mars.reset_store()
for t in np.linspace(-20*montu.DAY,20*montu.DAY,50):
    # Get MonTime object
    mtime = mtime_marstice + t

    # Calculate Mars position and store it
    mars.where_in_sky(mtime,Tebas,store=1)
mars.tabulate_store()

# Plot Hyades
hyades = allstars.get_stars_around(center=[aldebaran.data.RAJ2000,aldebaran.data.DecJ2000],radius=15,Vmag=[-1,5])
fig,ax = hyades.plot_stars(pad=0.0,labels=True,label_mag=4,figargs=dict(figsize=(8,8)))

for index in mars.position.index:
    mars_position = mars.position.loc[index]
    ax.plot(15*mars_position.RAJ2000,mars_position.DecJ2000,'ro',ms=10,alpha=0.3)

ax.set_title(f"Aldebaran conjunction during marstice at {-mtime_marstice.readable.year+1} \
b.c.e. {mtime_marstice.readable.month:02d}-{mtime_marstice.readable.day:02d} (Senenmut)",fontsize=13)
montu.Util.montu_mark(ax);

../_images/examples_MontuPython-Montunctions_89_0.png
../_images/examples_MontuPython-Montunctions_89_1.png

Powered by MontuPython. For more examples see MontuPython GitHub repo.

Jorge I. Zuluaga © 2023-present