S.T.a.R.S-ESE Reporting Tool — Version Publication 2026
Abstract
. 🔹 Outil de rapport STaRS-ESE — Version 2026 Auteur : Kevin Fradier — Chercheur indépendant 🇫🇷 Licence : CC BY-NC-ND 4.0 Objectif : pipeline complet avec sorties graphiques, partitions et hashes prêts pour publications. 📦 Structure du projet STaRS_ESE_Pipeline/ ├─ README.md ├─ LICENSE.md ├─ stars_ese_core.py # Code unifié + pipeline ├─ run_pipeline.py # Exemple d’exécution ├─ figures/ # Figures générées automatiquement ├─ outputs/ # Résultats numériques et hashes └─ examples/ # Jeux de données simulées pour test 🛠Fonctionnalités principales STaRS local : diagnostic par bassin stratigraphique Entropie, robustesse, SRS Graphique diversité enregistrée vs enveloppe bruit STaRS-NET : réseau inter-bassins Corrélation des robustesses locales NRSS, matrice de corrélation Graphique réseau prêt à publier ESE local : séquences et champs spatiaux Entropie, compression, Hurst Spectre radial, stabilité sous bruit Spectres graphiques et heatmaps ESE-NET : structure de test globale Robustesse multi-domaines Hachage traçable globalement Rapport automatique : Toutes les figures sont générées dansfigures/ Tous les scores et hashes sont sauvegardés dansoutputs/ Un rapport PDF optionnel (avec matplotlib/plotly + pandas) peut être produit Multi-domaines : fossiles, séquences symboliques, champs 2D Bottom-up, falsifiable et traçable Interface unique : une seule fonction pour tout exécuter 🔗 Pipeline recommandé (usage standardisé) from stars_ese_core import STaRS_ESE_pipeline, plot_pipeline_results import numpy as np # Exemple : 3 bassins, 2 séquences, 2 champs 2D strat_data = [np.array([5,3,0,2]), np.array([2,1,0,0]), np.array([0,0,1,0])] seq_data = ["AGCTTAGGCTAAGCTTAGGCTA"*5, "CGTAGCTAGCTAGCTA"*7] spatial_data = [np.random.randn(16,16), np.random.randn(16,16)] # Exécution pipeline results = STaRS_ESE_pipeline(strat_data, seq_data, spatial_data, verbose=True) # Génération figures et sauvegarde plot_pipeline_results(results, output_dir="figures", save_csv=True) 📊 Graphiques générés STaRS local : Courbes de diversité vs enveloppe de bruit Robustesse de la carte thermique par niveau STaRS-NET : Matrice de corrélation inter-bassins Graphique réseau (nœuds=bassins, bords=corrélations) ESE local : Spectres radiaux Heatmaps et cartes de stabilité ESE-NET : Graphique global multi-domaines Comparaison robustesse vs bruit 💾 Sorties numériques outputs/scores_STaRS.csv outputs/scores_STaRS_NET.csv outputs/scores_ESE.csv outputs/scores_ESE_NET.csv outputs/global_hash.txt Chaque fichier contient le hash associé pour garantir la traçabilité. 🧠Interprétation strictement autorisée ✅ Scores élevés → signal robuste ✅ Scores faibles → signal compatible bruit/artefact ❌ Aucun récit ❌ Aucune interprétation causale ❌ Pas de climat, extinction, ou scénario Stars et ESE ne disent pas ce qui s'est passé. Ils indiquent jusqu'où les données peuvent parler sans qu'on leur fasse dire plus. Tout le reste est hors protocole et interdit. 🏗 Étapes suivantes possibles (optionnel) STARS-TIME : ajouter des datations incertaines comme source de bruit STARS-EXT : testeur des artefacts d'extinction de masse Couplage avec ESE pour réseau multi-domaines Génération automatique de rapports PDF intégrant figures et scores Publication de pipelines reproduits par la communauté pour validation code Python complet pour le pipeline unifié STaRS × ESE, prêt à être utilisé, multi-domaines, traçable, avec figures, CSV et hashes. Il couvre STaRS local , STaRS-NET , ESE local , ESE-NET , et produit tout le reporting automatiquement . # stars_ese_core.py # Auteur : Kevin Fradier — Chercheur indépendant # Licence : CC BY-NC-ND 4.0 # Version 2026 — Pipeline unifié STaRS + ESE import numpy as np import matplotlib.pyplot as plt import hashlib import zlib import networkx as nx from hurst import compute_Hc from scipy.ndimage import gaussian_filter from itertools import combinations import os import csv AUTHOR_SIGNATURE = "Kevin Fradier | STaRS-ESE | 2026" # ----------------------------------- # UTILITAIRES # ----------------------------------- def compute_hash(obj): h = hashlib.sha256() h.update(str(obj).encode()) h.update(AUTHOR_SIGNATURE.encode()) return h.hexdigest() def shannon_entropy(seq): probs = [seq.count(c)/len(seq) for c in set(seq)] return -sum(p*np.log2(p) for p in probs if p>0) def compression_ratio(seq): raw = bytes(seq,'utf-8') return len(zlib.compress(raw))/len(raw) def hurst_exponent(seq): numeric = np.array([ord(c) for c in seq]) H, _, _ = compute_Hc(numeric, kind='change') return H def spatial_field_analysis(field, sigma_corr=3): field_corr = gaussian_filter(field, sigma=sigma_corr) fft2 = np.fft.fftshift(np.fft.fft2(field_corr)) power = np.abs(fft2)**2 return field_corr, power def radial_power_spectrum(power, bins=50): N = power.shape[0] kx, ky = np.meshgrid(np.fft.fftfreq(N), np.fft.fftfreq(N)) k = np.sqrt(kx**2 + ky**2) k_flat, p_flat = k.flatten(), power.flatten() radial_power = np.array([p_flat[(k_flat>=bins[i]) & (k_flat loss_rate noisy.append(level * mask) return noisy def strat_entropy(level): level = np.array(level) if np.sum(level)==0: return 0.0 p = level/np.sum(level) p = p[p>0] return -np.sum(p*np.log2(p)) def robustness_test(data, n_iter=100): original = np.array([np.sum(l) for l in data]) scores = [] for _ in range(n_iter): perturbed = simulate_taphonomic_noise(data) pert = np.array([np.sum(l) for l in perturbed]) corr = np.corrcoef(original, pert)[0,1] scores.append(corr) return np.nanmean(scores), np.nanstd(scores) # ----------------------------------- # MODULES STaRS # ----------------------------------- def STaRS_local(strat_data): entropies = [strat_entropy(l) for l in strat_data] mean_corr, std_corr = robustness_test(strat_data) srs_score = mean_corr # score principal result = { "mean_entropy": float(np.mean(entropies)), "robustness_corr": float(mean_corr), "robustness_std": float(std_corr), "SRS_score": float(srs_score), "hash": compute_hash(strat_data) } return result def STaRS_NET(local_results): # construire réseau basé sur corrélation SRS entre bassins scores = np.array([r["SRS_score"] for r in local_results]) n = len(scores) G = nx.Graph() for i in range(n): G.add_node(i, SRS_score=scores[i]) for i,j in combinations(range(n),2): corr = np.corrcoef([scores[i],scores[j]])[0,1] if not np.isnan(corr): G.add_edge(i,j,weight=corr) # NRSS = mean edge weight edges = [d['weight'] for u,v,d in G.edges(data=True)] nrss = np.mean(edges) if edges else 0.0 result = { "network": G, "NRSS": nrss, "hash": compute_hash(scores.tolist()) } return result # ----------------------------------- # MODULES ESE # ----------------------------------- def ESE_sequence(seq): return { "entropy": shannon_entropy(seq), "compression": compression_ratio(seq), "hurst": hurst_exponent(seq), "hash": compute_hash(seq) } def ESE_spatial(field): field_corr, power = spatial_field_analysis(field) k_mid, radial = radial_power_spectrum(power) mean_field = np.mean(field_corr) std_field = np.std(field_corr) result = { "mean_field": mean_field, "std_field": std_field, "radial_k": k_mid.tolist(), "radial_power": radial.tolist(), "hash": compute_hash(field.tolist()) } return result def ESE_NET(results): # Résumé multi-domaines values = [] for r in results: if "SRS_score" in r: values.append(r["SRS_score"]) elif "entropy" in r: values.append(r["entropy"]) mean_value = np.mean(values) if values else 0.0 result = { "mean_value": mean_value, "hash": compute_hash(values) } return result # ----------------------------------- # PIPELINE UNIFIÉ # ----------------------------------- def STaRS_ESE_pipeline(strat_data_list=[], seq_data_list=[], spatial_data_list=[], verbose=False): results = {"STaRS": [], "STaRS_NET": {}, "ESE": [], "ESE_NET": {}} # --- STaRS local --- for i, sd in enumerate(strat_data_list): r = STaRS_local(sd) results["STaRS"].append(r) if verbose: print(f"STaRS local bassin {i}:", r) # --- STaRS-NET --- if results["STaRS"]: r_net = STaRS_NET(results["STaRS"]) results["STaRS_NET"] = r_net if verbose: print("STaRS-NET:", {"NRSS": r_net["NRSS"], "hash": r_net["hash"]}) # --- ESE sequence --- for seq in seq_data_list: r = ESE_sequence(seq) results["ESE"].append(r) if verbose: print("ESE sequence:", r) # --- ESE spatial --- for field in spatial_data_list: r = ESE_spatial(field) results["ESE"].append(r) if verbose: print("ESE spatial:", r) # --- ESE-NET --- all_results = results["STaRS"] + results["ESE"] results["ESE_NET"] = ESE_NET(all_results) if verbose: print("ESE-NET:", results["ESE_NET"]) return results # ----------------------------------- # REPORTING # ----------------------------------- def plot_pipeline_results(results, output_dir="figures", save_csv=True): os.makedirs(output_dir, exist_ok=T
Publication details
- Journal / source
- Zenodo (CERN European Organization for Nuclear Research)
- Publication date
- 8 January 2026