{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":101849,"databundleVersionId":13093295,"sourceType":"competition"}],"dockerImageVersionId":31089,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## ARIEL DATA CHALLENGE 2025 - DATA VISUALIZATION TOOLKIT\n═══════════════════════════════════════════════════════════════\n\nThis code is designed to visualize Ariel telescope data.\nOptimized to run in Kaggle environment.\n\nFeatures:\n📊 Raw telescope images (AIRS-CH0 & FGS1)\n📈 Spectrum analysis and comparison\n🎭 Calibration data analysis\n📉 Statistical visualizations\n🌟 Scientific analysis plots","metadata":{}},{"cell_type":"code","source":"#!/usr/bin/env python3\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom pathlib import Path\nimport warnings\nwarnings.filterwarnings('ignore')\n\n# Scientific computing\nfrom scipy import stats\nfrom scipy.signal import savgol_filter\nfrom scipy.ndimage import gaussian_filter1d\n\n# Color palette settings\nplt.style.use('default')\nsns.set_palette(\"husl\")\nprint(\"=\" * 60)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-09-15T17:47:59.694719Z","iopub.execute_input":"2025-09-15T17:47:59.695041Z","iopub.status.idle":"2025-09-15T17:48:01.084074Z","shell.execute_reply.started":"2025-09-15T17:47:59.695017Z","shell.execute_reply":"2025-09-15T17:48:01.082998Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Load Data\n\nIn this section, we load the training and test datasets provided by the competition.  \nSteps:\n1. Read the CSV/JSON files\n2. Check the number of rows and columns\n3. Display a few sample entries","metadata":{}},{"cell_type":"code","source":"class VisualizationConfig:\n    \"\"\"Configuration for Kaggle environment\"\"\"\n    \n    # Kaggle Paths\n    INPUT_DIR = Path('/kaggle/input/ariel-data-challenge-2025')\n    WORKING_DIR = Path('/kaggle/working')\n    OUTPUT_DIR = Path('/kaggle/working/visualizations')\n    \n    # Local paths for testing (development)\n    LOCAL_INPUT_DIR = Path('./Data')\n    LOCAL_OUTPUT_DIR = Path('./visualizations')\n    \n    def __init__(self, use_kaggle=True):\n        self.use_kaggle = use_kaggle\n        \n        if use_kaggle:\n            self.input_dir = self.INPUT_DIR\n            self.output_dir = self.OUTPUT_DIR\n        else:\n            self.input_dir = self.LOCAL_INPUT_DIR  \n            self.output_dir = self.LOCAL_OUTPUT_DIR\n        \n        # Create output directory\n        self.output_dir.mkdir(exist_ok=True, parents=True)\n        \n        # Data paths\n        self.train_csv = self.input_dir / 'train.csv'\n        self.wavelengths_csv = self.input_dir / 'wavelengths.csv'\n        self.train_star_info = self.input_dir / 'train_star_info.csv'\n        self.test_star_info = self.input_dir / 'test_star_info.csv'\n        self.adc_info = self.input_dir / 'adc_info.csv'\n        \n        # Signal directories\n        self.train_dir = self.input_dir / 'train'\n        self.test_dir = self.input_dir / 'test'\n        \n        print(f\"📁 Input dir: {self.input_dir}\")\n        print(f\"📁 Output dir: {self.output_dir}\")\n\n# Check if running in Kaggle\ntry:\n    # Check for Kaggle file structure\n    if Path('/kaggle/input/ariel-data-challenge-2025').exists():\n        config = VisualizationConfig(use_kaggle=True)\n        print(\"🌐 Kaggle environment detected!\")\n    else:\n        config = VisualizationConfig(use_kaggle=False)\n        print(\"🏠 Local environment detected!\")\nexcept:\n    config = VisualizationConfig(use_kaggle=False)\n    print(\"🏠 Using local environment!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-15T18:05:34.637347Z","iopub.execute_input":"2025-09-15T18:05:34.638081Z","iopub.status.idle":"2025-09-15T18:05:34.653332Z","shell.execute_reply.started":"2025-09-15T18:05:34.638047Z","shell.execute_reply":"2025-09-15T18:05:34.652654Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class ArielDataVisualizer:\n    \"\"\"Ariel data visualization class\"\"\"\n    \n    def __init__(self, config):\n        self.config = config\n        self.adc_info = None\n        self.wavelengths = None\n        self.train_spectra = None\n        self.star_info = None\n        \n        # Color palettes\n        self.colors = {\n            'airs': '#FF6B6B',      # Red (Infrared)\n            'fgs1': '#4ECDC4',      # Turquoise (Visible)\n            'spectrum': '#45B7D1',   # Blue\n            'prediction': '#96CEB4', # Green\n            'uncertainty': '#FFEAA7' # Yellow\n        }\n        \n        print(\"🔧 ArielDataVisualizer initialized!\")\n    \n    def load_basic_data(self):\n        \"\"\"Load basic data files\"\"\"\n        print(\"\\n📊 Loading basic data...\")\n        \n        try:\n            # Wavelengths\n            if self.config.wavelengths_csv.exists():\n                self.wavelengths = pd.read_csv(self.config.wavelengths_csv)\n                print(f\"✅ Wavelengths: {self.wavelengths.shape}\")\n            \n            # ADC information\n            if self.config.adc_info.exists():\n                self.adc_info = pd.read_csv(self.config.adc_info)\n                print(f\"✅ ADC Info: {self.adc_info.shape}\")\n            \n            # Training spectra\n            if self.config.train_csv.exists():\n                self.train_spectra = pd.read_csv(self.config.train_csv)\n                print(f\"✅ Train Spectra: {self.train_spectra.shape}\")\n            \n            # Star information\n            if self.config.train_star_info.exists():\n                self.star_info = pd.read_csv(self.config.train_star_info)\n                print(f\"✅ Star Info: {self.star_info.shape}\")\n                \n        except Exception as e:\n            print(f\"⚠️ Data loading error: {e}\")\n    \n    def apply_adc_conversion(self, data, instrument):\n        \"\"\"Apply ADC conversion\"\"\"\n        if self.adc_info is None:\n            return data.astype(np.float64)\n            \n        try:\n            if instrument == 'FGS1':\n                gain = self.adc_info['FGS1_adc_gain'].iloc[0]\n                offset = self.adc_info['FGS1_adc_offset'].iloc[0]\n            else:  # AIRS-CH0\n                gain = self.adc_info['AIRS-CH0_adc_gain'].iloc[0]\n                offset = self.adc_info['AIRS-CH0_adc_offset'].iloc[0]\n            \n            return (data.astype(np.float64) / gain) + offset\n        except:\n            return data.astype(np.float64)\n    \n    def load_sample_planet_data(self, planet_id=None, max_frames=100):\n        \"\"\"Load sample planet data\"\"\"\n        print(f\"\\n🪐 Loading planet data...\")\n        \n        # If planet_id not specified, take the first planet\n        if planet_id is None:\n            if self.config.train_dir.exists():\n                planet_dirs = [d for d in self.config.train_dir.iterdir() if d.is_dir()]\n                if planet_dirs:\n                    planet_id = planet_dirs[0].name\n                else:\n                    print(\"❌ Planet data not found!\")\n                    return None, None\n        \n        planet_dir = self.config.train_dir / str(planet_id)\n        if not planet_dir.exists():\n            print(f\"❌ Planet {planet_id} not found!\")\n            return None, None\n        \n        signals = {}\n        \n        # AIRS-CH0 data\n        airs_files = list(planet_dir.glob('AIRS-CH0_signal_*.parquet'))\n        if airs_files:\n            try:\n                airs_data = pd.read_parquet(airs_files[0])\n                # Take first max_frames and reshape\n                airs_raw = airs_data.values[:max_frames]\n                airs_converted = self.apply_adc_conversion(airs_raw, 'AIRS-CH0')\n                # Reshape: (frames, 32, 356)\n                airs_images = airs_converted.reshape(-1, 32, 356)\n                signals['AIRS-CH0'] = airs_images\n                print(f\"✅ AIRS-CH0: {airs_images.shape}\")\n            except Exception as e:\n                print(f\"❌ AIRS-CH0 loading error: {e}\")\n        \n        # FGS1 data\n        fgs1_files = list(planet_dir.glob('FGS1_signal_*.parquet'))\n        if fgs1_files:\n            try:\n                fgs1_data = pd.read_parquet(fgs1_files[0])\n                # Take first max_frames and reshape\n                fgs1_raw = fgs1_data.values[:max_frames]\n                fgs1_converted = self.apply_adc_conversion(fgs1_raw, 'FGS1')\n                # Reshape: (frames, 32, 32)\n                fgs1_images = fgs1_converted.reshape(-1, 32, 32)\n                signals['FGS1'] = fgs1_images\n                print(f\"✅ FGS1: {fgs1_images.shape}\")\n            except Exception as e:\n                print(f\"❌ FGS1 loading error: {e}\")\n        \n        return signals, planet_id\n\n    def plot_overview_dashboard(self):\n        \"\"\"Create overview dashboard\"\"\"\n        print(\"\\n📊 Creating overview dashboard...\")\n        \n        fig = plt.figure(figsize=(20, 15))\n        \n        # 1. Dataset summary\n        if self.train_spectra is not None and self.star_info is not None:\n            \n            # Subplot grid\n            gs = fig.add_gridspec(3, 4, hspace=0.3, wspace=0.3)\n            \n            # 1. Spectrum distribution\n            ax1 = fig.add_subplot(gs[0, :2])\n            if self.wavelengths is not None:\n                # Wavelengths data is in a single row with 283 columns\n                # Check if we have multiple rows, if not use the first (and only) row\n                if len(self.wavelengths) > 1:\n                    wavelength_vals = self.wavelengths.iloc[1, :].values  # Second row has the actual wavelength values\n                else:\n                    wavelength_vals = self.wavelengths.iloc[0, :].values  # First row has the wavelength values\n                spectrum_cols = [col for col in self.train_spectra.columns if col != 'planet_id']\n                sample_spectra = self.train_spectra[spectrum_cols[:283]].iloc[:5]\n                \n                for i, (idx, spectrum) in enumerate(sample_spectra.iterrows()):\n                    # Make sure we have the same number of wavelengths and spectrum points\n                    n_points = min(len(wavelength_vals), len(spectrum.values))\n                    ax1.plot(wavelength_vals[:n_points], spectrum.values[:n_points], \n                           alpha=0.7, label=f'Planet {idx}')\n                \n                ax1.set_xlabel('Wavelength (µm)')\n                ax1.set_ylabel('Spectral Intensity')\n                ax1.set_title('🌟 Sample Planet Spectra')\n                ax1.legend()\n                ax1.grid(True, alpha=0.3)\n            \n            # 2. Planet parameters distribution\n            ax2 = fig.add_subplot(gs[0, 2:])\n            if 'temperature' in self.star_info.columns:\n                ax2.hist(self.star_info['temperature'], bins=30, alpha=0.7, \n                        color=self.colors['airs'], edgecolor='black')\n                ax2.set_xlabel('Star Temperature (K)')\n                ax2.set_ylabel('Frequency')\n                ax2.set_title('🌡️ Star Temperature Distribution')\n                ax2.grid(True, alpha=0.3)\n            \n            # 3. ADC information\n            ax3 = fig.add_subplot(gs[1, :2])\n            if self.adc_info is not None:\n                instruments = []\n                gains = []\n                offsets = []\n                \n                for col in self.adc_info.columns:\n                    if 'gain' in col:\n                        inst = col.replace('_adc_gain', '')\n                        instruments.append(inst)\n                        gains.append(self.adc_info[col].iloc[0])\n                        offsets.append(self.adc_info[col.replace('gain', 'offset')].iloc[0])\n                \n                x = np.arange(len(instruments))\n                width = 0.35\n                \n                ax3_twin = ax3.twinx()\n                bars1 = ax3.bar(x - width/2, gains, width, label='Gain', \n                              color=self.colors['airs'], alpha=0.7)\n                bars2 = ax3_twin.bar(x + width/2, offsets, width, label='Offset', \n                                   color=self.colors['fgs1'], alpha=0.7)\n                \n                ax3.set_xlabel('Instrument')\n                ax3.set_ylabel('Gain Value', color=self.colors['airs'])\n                ax3_twin.set_ylabel('Offset Value', color=self.colors['fgs1'])\n                ax3.set_title('🔧 ADC Conversion Parameters')\n                ax3.set_xticks(x)\n                ax3.set_xticklabels(instruments)\n                ax3.legend(loc='upper left')\n                ax3_twin.legend(loc='upper right')\n            \n            # 4. Dataset statistics\n            ax4 = fig.add_subplot(gs[1, 2:])\n            stats_data = {\n                'Total Planets': len(self.train_spectra),\n                'Spectral Points': len([col for col in self.train_spectra.columns if col != 'planet_id']),\n                'Wavelength Range': f\"{self.wavelengths.iloc[0 if len(self.wavelengths) == 1 else 1, 0]:.2f}-{self.wavelengths.iloc[0 if len(self.wavelengths) == 1 else 1, -1]:.2f} µm\" if self.wavelengths is not None else \"N/A\"\n            }\n            \n            stats_text = \"\\n\".join([f\"{k}: {v}\" for k, v in stats_data.items()])\n            ax4.text(0.1, 0.5, stats_text, fontsize=14, transform=ax4.transAxes,\n                    verticalalignment='center', bbox=dict(boxstyle=\"round,pad=0.3\", \n                    facecolor=self.colors['uncertainty'], alpha=0.7))\n            ax4.set_title('📈 Dataset Statistics')\n            ax4.axis('off')\n            \n            # 5. Spectral summary\n            ax5 = fig.add_subplot(gs[2, :])\n            if len(spectrum_cols) >= 283:\n                all_spectra = self.train_spectra[spectrum_cols[:283]].values\n                \n                # Mean and standard deviation\n                mean_spectrum = np.mean(all_spectra, axis=0)\n                std_spectrum = np.std(all_spectra, axis=0)\n                \n                # Safe wavelength access\n                if self.wavelengths is not None:\n                    if len(self.wavelengths) > 1:\n                        wavelength_vals = self.wavelengths.iloc[1, :283].values\n                    else:\n                        wavelength_vals = self.wavelengths.iloc[0, :283].values\n                else:\n                    wavelength_vals = range(283)\n                \n                ax5.fill_between(wavelength_vals, \n                               mean_spectrum - std_spectrum,\n                               mean_spectrum + std_spectrum,\n                               alpha=0.3, color=self.colors['spectrum'], label='±1σ')\n                ax5.plot(wavelength_vals, mean_spectrum, \n                        color=self.colors['spectrum'], linewidth=2, label='Mean')\n                \n                ax5.set_xlabel('Wavelength (µm)')\n                ax5.set_ylabel('Spectral Intensity')\n                ax5.set_title('📊 Overall Spectral Profile (Mean ± Std Dev)')\n                ax5.legend()\n                ax5.grid(True, alpha=0.3)\n        \n        plt.suptitle('🚀 ARIEL DATA CHALLENGE 2025 - DATASET OVERVIEW', \n                    fontsize=16, fontweight='bold')\n        plt.savefig(self.config.output_dir / 'overview_dashboard.png', \n                   dpi=300, bbox_inches='tight')\n        plt.show()\n        print(f\"✅ Dashboard saved: {self.config.output_dir / 'overview_dashboard.png'}\")\n\n    def plot_telescope_images(self, signals, planet_id, num_frames=6):\n        \"\"\"Visualize telescope images\"\"\"\n        print(f\"\\n📸 Plotting telescope images - Planet {planet_id}...\")\n        \n        if not signals:\n            print(\"❌ Image data not found!\")\n            return\n        \n        # Separate figure for each instrument\n        for instrument, images in signals.items():\n            if len(images) == 0:\n                continue\n                \n            fig, axes = plt.subplots(2, 3, figsize=(15, 10))\n            axes = axes.flatten()\n            \n            # Show first num_frames images\n            frames_to_show = min(num_frames, len(images))\n            \n            for i in range(frames_to_show):\n                ax = axes[i]\n                \n                # Display image\n                im = ax.imshow(images[i], cmap='viridis', aspect='auto')\n                ax.set_title(f'Frame {i+1}')\n                ax.set_xlabel('X Pixel')\n                ax.set_ylabel('Y Pixel')\n                \n                # Add colorbar\n                plt.colorbar(im, ax=ax, fraction=0.046, pad=0.04)\n            \n            # Hide empty subplots\n            for i in range(frames_to_show, len(axes)):\n                axes[i].axis('off')\n            \n            plt.suptitle(f'📡 {instrument} Telescope Images - Planet {planet_id}', \n                        fontsize=14, fontweight='bold')\n            plt.tight_layout()\n            plt.savefig(self.config.output_dir / f'{instrument}_images_planet_{planet_id}.png', \n                       dpi=300, bbox_inches='tight')\n            plt.show()\n            \n            print(f\"✅ {instrument} images saved\")\n\n    def plot_signal_analysis(self, signals, planet_id):\n        \"\"\"Signal analysis plots\"\"\"\n        print(f\"\\n📈 Signal analysis - Planet {planet_id}...\")\n        \n        if not signals:\n            return\n        \n        fig, axes = plt.subplots(2, 2, figsize=(16, 12))\n        \n        for idx, (instrument, images) in enumerate(signals.items()):\n            if len(images) == 0:\n                continue\n            \n            # Average signal level per frame\n            mean_signals = []\n            std_signals = []\n            \n            for frame in images:\n                mean_signals.append(np.mean(frame))\n                std_signals.append(np.std(frame))\n            \n            # 1. Time series - average signal\n            ax1 = axes[0, idx] if idx < 2 else axes[0, 0]\n            time_steps = np.arange(len(mean_signals))\n            \n            ax1.plot(time_steps, mean_signals, color=self.colors['airs'] if 'AIRS' in instrument else self.colors['fgs1'])\n            ax1.fill_between(time_steps, \n                           np.array(mean_signals) - np.array(std_signals),\n                           np.array(mean_signals) + np.array(std_signals),\n                           alpha=0.3)\n            ax1.set_title(f'{instrument} - Average Signal vs Time')\n            ax1.set_xlabel('Frame Number')\n            ax1.set_ylabel('Signal Level')\n            ax1.grid(True, alpha=0.3)\n            \n            # 2. Signal distribution histogram\n            ax2 = axes[1, idx] if idx < 2 else axes[1, 0]\n            all_pixels = images.flatten()\n            \n            ax2.hist(all_pixels, bins=50, alpha=0.7, density=True,\n                    color=self.colors['airs'] if 'AIRS' in instrument else self.colors['fgs1'])\n            ax2.set_title(f'{instrument} - Pixel Value Distribution')\n            ax2.set_xlabel('Pixel Value')\n            ax2.set_ylabel('Density')\n            ax2.grid(True, alpha=0.3)\n            \n            # Add statistics\n            stats_text = f'Mean: {np.mean(all_pixels):.2f}\\nStd: {np.std(all_pixels):.2f}\\nMin: {np.min(all_pixels):.2f}\\nMax: {np.max(all_pixels):.2f}'\n            ax2.text(0.05, 0.95, stats_text, transform=ax2.transAxes, \n                    verticalalignment='top', bbox=dict(boxstyle=\"round,pad=0.3\", facecolor='white', alpha=0.8))\n        \n        plt.suptitle(f'📊 Signal Analysis - Planet {planet_id}', fontsize=14, fontweight='bold')\n        plt.tight_layout()\n        plt.savefig(self.config.output_dir / f'signal_analysis_planet_{planet_id}.png', \n                   dpi=300, bbox_inches='tight')\n        plt.show()\n        \n        print(f\"✅ Signal analysis saved\")\n\n    def plot_spectral_comparison(self, num_planets=5):\n        \"\"\"Spectral comparison\"\"\"\n        print(f\"\\n Spectral comparison - {num_planets} PLANET...\")\n        \n        if self.train_spectra is None or self.wavelengths is None:\n            print(\"❌ No spectrum data found!\")\n            return\n        \n        fig, axes = plt.subplots(2, 2, figsize=(16, 12))\n        \n        # Spektrum sütunlarını al\n        spectrum_cols = [col for col in self.train_spectra.columns if col != 'planet_id'][:283]\n        # Safe wavelength access\n        if len(self.wavelengths) > 1:\n            wavelength_vals = self.wavelengths.iloc[1, :len(spectrum_cols)].values\n        else:\n            wavelength_vals = self.wavelengths.iloc[0, :len(spectrum_cols)].values\n        \n        # 1. Bireysel spektrumlar\n        ax1 = axes[0, 0]\n        for i in range(min(num_planets, len(self.train_spectra))):\n            spectrum = self.train_spectra[spectrum_cols].iloc[i]\n            ax1.plot(wavelength_vals, spectrum.values, alpha=0.8, \n                    label=f'Planet {self.train_spectra.iloc[i][\"planet_id\"]}')\n        \n        ax1.set_xlabel('Wavelength (µm)')\n        ax1.set_ylabel('Spectral Density')\n        ax1.set_title('🪐 Individual Planet Spectra')\n        ax1.legend()\n        ax1.grid(True, alpha=0.3)\n        \n        # 2. Normalize edilmiş spektrumlar\n        ax2 = axes[0, 1]\n        for i in range(min(num_planets, len(self.train_spectra))):\n            spectrum = self.train_spectra[spectrum_cols].iloc[i]\n            # Min-max normalization\n            spectrum_norm = (spectrum - spectrum.min()) / (spectrum.max() - spectrum.min())\n            ax2.plot(wavelength_vals, spectrum_norm.values, alpha=0.8,\n                    label=f'Planet {self.train_spectra.iloc[i][\"planet_id\"]}')\n        \n        ax2.set_xlabel('Wavelength (µm)')\n        ax2.set_ylabel('Normalized Spectral Density')\n        ax2.set_title('📊 Normalized Spectra')\n        ax2.legend()\n        ax2.grid(True, alpha=0.3)\n        \n        # 3. Average spectrum and variation\n        ax3 = axes[1, 0]\n        all_spectra = self.train_spectra[spectrum_cols].values\n        mean_spectrum = np.mean(all_spectra, axis=0)\n        std_spectrum = np.std(all_spectra, axis=0)\n        \n        ax3.fill_between(wavelength_vals, \n                        mean_spectrum - std_spectrum,\n                        mean_spectrum + std_spectrum,\n                        alpha=0.3, color=self.colors['spectrum'], label='±1σ')\n        ax3.plot(wavelength_vals, mean_spectrum, \n                color=self.colors['spectrum'], linewidth=2, label='Ortalama')\n        \n        ax3.set_xlabel('Wavelength (µm)')\n        ax3.set_ylabel('Spectral Density')\n        ax3.set_title('📈 Mean Spectrum ± Standard Deviation')\n        ax3.legend()\n        ax3.grid(True, alpha=0.3)\n        \n        # 4. heatmap\n        ax4 = axes[1, 1]\n        sample_spectra = self.train_spectra[spectrum_cols].iloc[:min(20, len(self.train_spectra))]\n        \n        im = ax4.imshow(sample_spectra.T, aspect='auto', cmap='viridis')\n        ax4.set_xlabel('Planet Index')\n        ax4.set_ylabel('Wavelength Index')\n        ax4.set_title('Spectral Diversity Map')\n        plt.colorbar(im, ax=ax4, fraction=0.046, pad=0.04)\n        \n        plt.suptitle('🔬 SPECTRAL ANALYSIS COMPRASION', fontsize=14, fontweight='bold')\n        plt.tight_layout()\n        plt.savefig(self.config.output_dir / 'spectral_comparison.png', \n                   dpi=300, bbox_inches='tight')\n        plt.show()\n        \n        print(f\"✅ Spectral comparison saved\")\n\n    def create_summary_report(self):\n        \"\"\"Create summary report\"\"\"\n        print(\"\\n📋 Creating summary report...\")\n        \n        report = f\"\"\"\n# 🚀 ARIEL DATA CHALLENGE 2025 - DATA ANALYSIS REPORT\n\n## 📊 Dataset Summary\n- **Total Planets**: {len(self.train_spectra) if self.train_spectra is not None else 'N/A'}\n- **Spectral Points**: {len([col for col in self.train_spectra.columns if col != 'planet_id']) if self.train_spectra is not None else 'N/A'}\n- **Wavelength Range**: {f\"{self.wavelengths.iloc[0 if len(self.wavelengths) == 1 else 1, 0]:.3f} - {self.wavelengths.iloc[0 if len(self.wavelengths) == 1 else 1, -1]:.3f} µm\" if self.wavelengths is not None else 'N/A'}\n\n## 🔧 Instrument Information\n\"\"\"\n        \n        if self.adc_info is not None:\n            for col in self.adc_info.columns:\n                if 'gain' in col:\n                    inst = col.replace('_adc_gain', '')\n                    gain = self.adc_info[col].iloc[0]\n                    offset = self.adc_info[col.replace('gain', 'offset')].iloc[0]\n                    report += f\"- **{inst}**: Gain={gain:.4f}, Offset={offset:.4f}\\n\"\n        \n        report += f\"\"\"\n## 📈 Statistical Summary\n\"\"\"\n        \n        if self.train_spectra is not None:\n            spectrum_cols = [col for col in self.train_spectra.columns if col != 'planet_id']\n            all_spectra = self.train_spectra[spectrum_cols].values\n            \n            report += f\"\"\"\n- **Average Spectral Value**: {np.mean(all_spectra):.6f}\n- **Standard Deviation**: {np.std(all_spectra):.6f}\n- **Minimum Value**: {np.min(all_spectra):.6f}\n- **Maximum Value**: {np.max(all_spectra):.6f}\n\n## 🎯 Visualization Outputs\n- Overview Dashboard: `overview_dashboard.png`\n- Spectral Comparison: `spectral_comparison.png`\n- Telescope Images: `[INSTRUMENT]_images_planet_[ID].png`\n- Signal Analysis: `signal_analysis_planet_[ID].png`\n\n## 📝 Notes\nThis report was generated automatically.\nReview individual plot files for detailed analysis.\n\n---\n\n\"\"\"\n        \n        # Save report\n        with open(self.config.output_dir / 'analysis_report.md', 'w', encoding='utf-8') as f:\n            f.write(report)\n        \n        print(f\"✅ Report saved: {self.config.output_dir / 'analysis_report.md'}\")\n        print(\"\\n\" + \"=\"*50)\n        print(report)\n        print(\"=\"*50)\n\n\ndef main():\n    \"\"\"Main execution function\"\"\"\n    print(\"\\n🎨 Starting Ariel Data Visualization...\")\n    print(\"=\" * 60)\n    \n    try:\n        # Initialize visualizer\n        visualizer = ArielDataVisualizer(config)\n        \n        # 1. Load basic data\n        visualizer.load_basic_data()\n        \n        # 2. Overview dashboard\n        visualizer.plot_overview_dashboard()\n        \n        # 3. Spectral comparison\n        visualizer.plot_spectral_comparison(num_planets=8)\n        \n        # 4. Load sample planet data and visualize\n        signals, planet_id = visualizer.load_sample_planet_data(max_frames=50)\n        if signals:\n            visualizer.plot_telescope_images(signals, planet_id, num_frames=6)\n            visualizer.plot_signal_analysis(signals, planet_id)\n        \n        # 5. Summary report\n        visualizer.create_summary_report()\n        \n        print(\"\\n🎉 ALL VISUALIZATIONS COMPLETED!\")\n        print(f\"📁 Outputs: {config.output_dir}\")\n        print(\"=\" * 60)\n        \n    except Exception as e:\n        print(f\"❌ Error occurred: {e}\")\n        import traceback\n        traceback.print_exc()\n\nif __name__ == \"__main__\":\n    main()\n\nprint(\"\\n🐍 Ok! 🚀\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-15T18:14:09.324661Z","iopub.execute_input":"2025-09-15T18:14:09.325015Z","iopub.status.idle":"2025-09-15T18:14:30.917221Z","shell.execute_reply.started":"2025-09-15T18:14:09.32499Z","shell.execute_reply":"2025-09-15T18:14:30.916364Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile\nimport os\n\n# Create ZIP all visualizations\ndef create_visualization_zip():\n    zip_path = '/kaggle/working/ariel_visualizations.zip'\n    \n    with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:\n        # add working data\n        for root, dirs, files in os.walk('/kaggle/working/visualizations'):\n            for file in files:\n                file_path = os.path.join(root, file)\n                # Use only the file name in the ZIP\n                zipf.write(file_path, file)\n    \n    print(f\"✅ ZIP file as created: {zip_path}\")\n    return zip_path\n\n# Create ZIP and DOWNLAD\nzip_file = create_visualization_zip()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-15T17:49:58.047161Z","iopub.execute_input":"2025-09-15T17:49:58.047459Z","iopub.status.idle":"2025-09-15T17:49:58.262611Z","shell.execute_reply.started":"2025-09-15T17:49:58.047437Z","shell.execute_reply":"2025-09-15T17:49:58.261525Z"}},"outputs":[],"execution_count":null}]}