{"metadata":{"exported_at":"2026-04-10T15:39:29.232Z","project":"World Cycles Multi-Dimensional Timeline","description":"Analysis source code for independent replication","license":"REGENESIS Open Source License","files_included":[]},"typescript_source":{},"python_replication_script":"#!/usr/bin/env python3\n\"\"\"\nWorld Cycles Fourier Analysis — Independent Replication Script\nProject: World Cycles Multi-Dimensional Timeline\nSource: worldcycles.abacusai.app\nRepository: https://github.com/nbbulk-dotcom/world-cycles-platform\nLicense: REGENESIS Open Source License\n\nThis script performs independent Fourier spectral analysis on the\nWorld Cycles event dataset to verify the 9 empirically detected cycles.\n\nRequirements: pip install numpy scipy matplotlib pandas requests\n\nUsage:\n  python replicate_fourier.py                    # Uses live API\n  python replicate_fourier.py --csv events.csv   # Uses local CSV\n\"\"\"\n\nimport numpy as np\nfrom scipy import fft\nfrom scipy.signal import find_peaks\nimport matplotlib.pyplot as plt\nimport json\nimport sys\n\n# The 9 empirically detected cycles (Tartary 360-day years)\nKNOWN_CYCLES = {\n    'Political': 27,\n    'Economic': 55,\n    'Uranus': 81,\n    'Generational': 107,\n    'Imperial': 171,\n    'Civilizational': 270,\n    'Meta': 600,\n    'Great': 2500,\n    'Master': 5500,\n}\n\ndef load_events_from_api(url='https://worldcycles.abacusai.app/api/export?dataset=events'):\n    \"\"\"Fetch events from the live API.\"\"\"\n    import requests\n    resp = requests.get(url)\n    data = resp.json()\n    return data.get('data', [])\n\ndef load_events_from_csv(filepath):\n    \"\"\"Load events from a local CSV file.\"\"\"\n    import pandas as pd\n    df = pd.read_csv(filepath)\n    return df.to_dict('records')\n\ndef events_to_timeseries(events, bin_size=1):\n    \"\"\"Convert event list to annual density time series.\"\"\"\n    years = [e['year'] for e in events if e.get('year') is not None]\n    if not years:\n        return np.array([]), np.array([])\n    min_year = min(years)\n    max_year = max(years)\n    bins = np.arange(min_year, max_year + bin_size, bin_size)\n    counts, _ = np.histogram(years, bins=bins)\n    bin_centers = (bins[:-1] + bins[1:]) / 2\n    return bin_centers, counts.astype(float)\n\ndef fourier_analysis(years, signal):\n    \"\"\"Perform FFT and return frequencies, power spectrum.\"\"\"\n    n = len(signal)\n    dt = years[1] - years[0] if len(years) > 1 else 1\n    # Remove mean (detrend)\n    signal_detrended = signal - np.mean(signal)\n    # Apply Hanning window\n    window = np.hanning(n)\n    signal_windowed = signal_detrended * window\n    # FFT\n    spectrum = fft.fft(signal_windowed)\n    freqs = fft.fftfreq(n, d=dt)\n    power = np.abs(spectrum) ** 2\n    # Take positive frequencies only\n    pos_mask = freqs > 0\n    return freqs[pos_mask], power[pos_mask]\n\ndef detect_peaks_and_match(freqs, power, known_cycles, tolerance=0.15):\n    \"\"\"Find spectral peaks and match to known cycles.\"\"\"\n    periods = 1.0 / freqs\n    # Find peaks in power spectrum\n    peak_indices, properties = find_peaks(power, height=np.median(power) * 2, distance=3)\n    results = []\n    for idx in peak_indices:\n        period = periods[idx]\n        pwr = power[idx]\n        snr = pwr / np.median(power)\n        # Check if this matches a known cycle\n        match = None\n        for name, cyc_period in known_cycles.items():\n            if abs(period - cyc_period) / cyc_period < tolerance:\n                match = name\n                break\n        results.append({\n            'period': round(period, 2),\n            'power': round(pwr, 2),\n            'snr': round(snr, 2),\n            'matched_cycle': match,\n        })\n    # Sort by power descending\n    results.sort(key=lambda x: x['power'], reverse=True)\n    return results\n\ndef monte_carlo_significance(years, signal, n_surrogates=10000):\n    \"\"\"Test significance via Monte Carlo surrogate analysis.\"\"\"\n    n = len(signal)\n    freqs, real_power = fourier_analysis(years, signal)\n    real_max = np.max(real_power)\n    count_exceeding = 0\n    for _ in range(n_surrogates):\n        surrogate = np.random.permutation(signal)\n        _, surr_power = fourier_analysis(years, surrogate)\n        if np.max(surr_power) >= real_max:\n            count_exceeding += 1\n    p_value = count_exceeding / n_surrogates\n    return p_value\n\ndef main():\n    # Load data\n    if '--csv' in sys.argv:\n        idx = sys.argv.index('--csv')\n        filepath = sys.argv[idx + 1]\n        print(f'Loading events from CSV: {filepath}')\n        events = load_events_from_csv(filepath)\n    else:\n        print('Fetching events from worldcycles.abacusai.app API...')\n        events = load_events_from_api()\n\n    print(f'Loaded {len(events)} events')\n\n    # Convert to time series\n    years, signal = events_to_timeseries(events)\n    print(f'Time series: {int(years[0])} to {int(years[-1])} ({len(years)} bins)')\n\n    # Fourier analysis\n    freqs, power = fourier_analysis(years, signal)\n    periods = 1.0 / freqs\n\n    # Detect peaks\n    peaks = detect_peaks_and_match(freqs, power, KNOWN_CYCLES)\n\n    print('\n=== SPECTRAL PEAKS DETECTED ===')\n    print(f'{\"Period (yr)\":>12}  {\"SNR\":>8}  {\"Matched Cycle\":<20}')\n    print('-' * 45)\n    matched = 0\n    for p in peaks[:20]:  # Top 20\n        label = p['matched_cycle'] or '—'\n        if p['matched_cycle']:\n            matched += 1\n        print(f'{p[\"period\"]:>12.1f}  {p[\"snr\"]:>8.1f}x  {label:<20}')\n\n    print(f'\nMatched {matched} of {len(KNOWN_CYCLES)} known cycles in top {min(20, len(peaks))} peaks')\n\n    # Monte Carlo (optional — slow)\n    if '--monte-carlo' in sys.argv:\n        print('\nRunning Monte Carlo significance test (10,000 surrogates)...')\n        p_val = monte_carlo_significance(years, signal)\n        print(f'P-value: {p_val}')\n        if p_val < 0.001:\n            print('RESULT: Patterns are statistically significant (p < 0.001)')\n\n    # Plot\n    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10))\n\n    # Event density\n    ax1.bar(years, signal, width=1, color='#4ecdc4', alpha=0.7)\n    ax1.set_xlabel('Year')\n    ax1.set_ylabel('Event Count')\n    ax1.set_title('Historical Event Density (Annual)')\n\n    # Power spectrum\n    mask = (periods > 10) & (periods < 6000)\n    ax2.plot(periods[mask], power[mask], color='#ff6b6b', linewidth=0.8)\n    # Mark known cycles\n    for name, period in KNOWN_CYCLES.items():\n        ax2.axvline(x=period, color='#ffd93d', alpha=0.5, linestyle='--', linewidth=0.8)\n        ax2.text(period, ax2.get_ylim()[1] * 0.9, name, rotation=90,\n                 fontsize=7, ha='right', va='top', color='#ffd93d')\n    ax2.set_xlabel('Period (years)')\n    ax2.set_ylabel('Spectral Power')\n    ax2.set_title('Fourier Power Spectrum — World Cycles')\n    ax2.set_xscale('log')\n\n    plt.tight_layout()\n    plt.savefig('world_cycles_fourier_analysis.png', dpi=150, bbox_inches='tight')\n    print('\nPlot saved: world_cycles_fourier_analysis.png')\n    plt.show()\n\nif __name__ == '__main__':\n    main()\n"}