#!/usr/bin/env python3
"""
Project 33: Planetary Dignities & Character (VEDIC/SIDEREAL)
Re-analysis using Sidereal Zodiac (Lahiri Ayanamsa).
Does Essential Dignity (Domicile/Exaltation) correlate with Career Success/Field?
"""
import sys
import pandas as pd
import numpy as np
import swisseph as swe
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns
from pathlib import Path
from datetime import datetime
# Import the data extracted from Project 16
from source_data import CREATIVE_GENIUSES
OUTPUT_DIR = Path(__file__).parent
swe.set_ephe_path(None)
# --- VEDIC SETUP ---
# Set Sidereal Mode to Lahiri
swe.set_sid_mode(swe.SIDM_LAHIRI, 0, 0)
print("Sidereal Mode: Lahiri Ayanamsa Set.")
SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo',
'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces']
PLANETS = {
'Sun': swe.SUN,
'Moon': swe.MOON,
'Mercury': swe.MERCURY,
'Venus': swe.VENUS,
'Mars': swe.MARS,
'Jupiter': swe.JUPITER,
'Saturn': swe.SATURN
}
# Dignity Map (Sign Indices 0-11)
# Using standard Domicile/Exaltation scheme applied to Sidereal Signs
DIGNITIES = {
'Sun': {'Dom': [4], 'Exalt': [0], 'Det': [10], 'Fall': [6]},
'Moon': {'Dom': [3], 'Exalt': [1], 'Det': [9], 'Fall': [7]},
'Mercury':{'Dom': [2, 5], 'Exalt': [5], 'Det': [8, 11], 'Fall': [11]}, # Vir is Dom+Exalt
'Venus': {'Dom': [1, 6], 'Exalt': [11], 'Det': [0, 7], 'Fall': [5]},
'Mars': {'Dom': [0, 7], 'Exalt': [9], 'Det': [6, 1], 'Fall': [3]},
'Jupiter':{'Dom': [8, 11], 'Exalt': [3], 'Det': [2, 5], 'Fall': [9]},
'Saturn': {'Dom': [9, 10], 'Exalt': [6], 'Det': [3, 4], 'Fall': [0]},
}
def get_dignity_score(planet, sign_idx):
"""
Calculate essential dignity score.
Simple weighted model:
Domicile = +5
Exaltation = +4
Detriment = -5
Fall = -4
Peregrine = 0
"""
rules = DIGNITIES[planet]
score = 0
if sign_idx in rules['Dom']: score += 5
if sign_idx in rules['Exalt']: score += 4
if sign_idx in rules['Det']: score -= 5
if sign_idx in rules['Fall']: score -= 4
return score
def get_dignity_label(planet, sign_idx):
rules = DIGNITIES[planet]
labels = []
if sign_idx in rules['Dom']: labels.append("Domicile")
if sign_idx in rules['Exalt']: labels.append("Exaltation")
if sign_idx in rules['Det']: labels.append("Detriment")
if sign_idx in rules['Fall']: labels.append("Fall")
if not labels: return "Peregrine"
return "/".join(labels)
def get_julian_day(date_str, time_str):
try:
dt = datetime.strptime(f"{date_str} {time_str}", "%Y-%m-%d %H:%M")
except ValueError:
try:
dt = datetime.strptime(f"{date_str} {time_str}", "%Y-%m-%d %H:%M:%S")
except:
dt = datetime.strptime(date_str, "%Y-%m-%d")
dt = dt.replace(hour=12)
return swe.julday(dt.year, dt.month, dt.day, dt.hour + dt.minute/60.0)
def analyze_chart(name, date, time, field):
jd = get_julian_day(date, time)
row = {
'name': name,
'occupation': field,
}
total_score = 0
for planet, pid in PLANETS.items():
# calculate sidereal position
res = swe.calc_ut(jd, pid, swe.FLG_SIDEREAL)[0][0]
sign_idx = int(res / 30) % 12
score = get_dignity_score(planet, sign_idx)
label = get_dignity_label(planet, sign_idx)
row[f'{planet}_Sign'] = SIGNS[sign_idx]
row[f'{planet}_Score'] = score
row[f'{planet}_Dignity'] = label
total_score += score
row['Total_Dignity'] = total_score
return row
def main():
print("Project 33: Planetary Dignities Analysis (VEDIC)")
print("-" * 50)
data = []
for entry in CREATIVE_GENIUSES:
# Entry: (Name, Date, Time, Field, Achievement)
data.append(analyze_chart(entry[0], entry[1], entry[2], entry[3]))
df = pd.DataFrame(data)
# Save processed data
df.to_csv(OUTPUT_DIR / 'dignities_analyzed_vedic.csv', index=False)
print(f"Analyzed {len(df)} charts (Vedic).")
# --- Statistical Analysis ---
print("\n--- Average Dignity Scores by Occupation (Vedic) ---")
score_cols = [f'{p}_Score' for p in PLANETS.keys()]
grouped = df.groupby('occupation')[score_cols].mean()
print(grouped.round(2))
# Test Significance
print("\n--- Significance Tests (T-Test vs Rest of Population) ---")
results = []
occupations = df['occupation'].unique()
for occ in occupations:
occ_df = df[df['occupation'] == occ]
rest_df = df[df['occupation'] != occ]
print(f"\nOccupation: {occ.upper()} (n={len(occ_df)})")
for planet in PLANETS.keys():
col = f'{planet}_Score'
t_stat, p_val = stats.ttest_ind(occ_df[col], rest_df[col], equal_var=False)
diff = occ_df[col].mean() - rest_df[col].mean()
if p_val < 0.10:
sig = "**" if p_val < 0.05 else "*"
print(f" {planet}: Diff={diff:+.2f}, p={p_val:.4f} {sig}")
results.append({
'Occupation': occ,
'Planet': planet,
'Mean_Occ': occ_df[col].mean(),
'Mean_Rest': rest_df[col].mean(),
'Diff': diff,
'P_Value': p_val
})
# --- Visualization ---
create_plots(df, results)
# --- Generate Report ---
generate_report(df, results)
def create_plots(df, results_list):
# 1. Heatmap of Average Scores
score_cols = [f'{p}_Score' for p in PLANETS.keys()]
global_mean = df[score_cols].mean()
# Calculate difference from global mean for each occupation
grouped = df.groupby('occupation')[score_cols].mean()
diff_matrix = grouped - global_mean
plt.figure(figsize=(10, 6))
sns.heatmap(diff_matrix, cmap='RdBu_r', center=0, annot=True, fmt='.2f')
plt.title('Vedic Dignity Score Deviation by Occupation\n(Positive = Higher Dignity than Average)')
plt.tight_layout()
plt.savefig(OUTPUT_DIR / 'dignity_heatmap_vedic.png')
plt.close()
# 2. Distro of Total Dignity
plt.figure(figsize=(10, 6))
sns.kdeplot(data=df, x='Total_Dignity', hue='occupation', fill=False)
plt.title('Distribution of Total Chart Dignity (Vedic) by Occupation')
plt.savefig(OUTPUT_DIR / 'total_dignity_dist_vedic.png')
plt.close()
def generate_report(df, results):
with open(OUTPUT_DIR / 'RESULTS_VEDIC.md', 'w') as f:
f.write("# Project 33: Planetary Dignities & Character (VEDIC)\n\n")
f.write("## Overview\n")
f.write(f"Re-analyzed **{len(df)}** charts using **Sidereal Zodiac (Lahiri)**.\n")
f.write("Did shifting to Vedic placements improve the signal?\n\n")
f.write("## Significant Findings (P < 0.10)\n")
f.write("| Occupation | Planet | Mean Score | Vs Rest | Diff | P-Value |\n")
f.write("|---|---|---|---|---|---|\n")
results.sort(key=lambda x: x['P_Value'])
for r in results:
sig = "**" if r['P_Value'] < 0.05 else ""
f.write(f"| {r['Occupation']} | {r['Planet']} | {r['Mean_Occ']:.2f} | {r['Mean_Rest']:.2f} | {r['Diff']:+.2f} | {sig}{r['P_Value']:.4f}{sig} |\n")
f.write("\n## Interpretation\n")
strongest = results[0] if results else None
if strongest and strongest['P_Value'] < 0.05:
f.write(f"The most significant finding in Vedic is **{strongest['Occupation']} and {strongest['Planet']}** (Diff: {strongest['Diff']:.2f}). ")
if strongest['Diff'] > 0:
f.write(f"This group shows significantly stronger {strongest['Planet']} dignity in the Sidereal chart.\n")
else:
f.write(f"This group shows significantly WEAKER {strongest['Planet']} dignity (Debility) in the Sidereal chart.\n")
else:
f.write("No strong correlations (p<0.05) found in the Vedic analysis.\n")
if __name__ == "__main__":
main()