{"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,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":9629432,"sourceType":"datasetVersion","datasetId":5846888},{"sourceId":13118064,"sourceType":"datasetVersion","datasetId":8309969}],"dockerImageVersionId":31089,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nimport os\nimport glob\nfrom scipy.signal import medfilt, savgol_filter\nfrom astropy.stats import sigma_clip\nimport pandas as pd\n!pip install --no-index --find-links=/kaggle/input/ariel-2024-pqdm pqdm\nfrom pqdm.threads import pqdm\nimport warnings\nimport joblib\nfrom sklearn.preprocessing import StandardScaler\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler\nfrom torch.utils.data import DataLoader, TensorDataset","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:52.755457Z","iopub.execute_input":"2025-09-20T14:00:52.756163Z","iopub.status.idle":"2025-09-20T14:00:56.638693Z","shell.execute_reply.started":"2025-09-20T14:00:52.756127Z","shell.execute_reply":"2025-09-20T14:00:56.637404Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"MODEE = 'test/'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:56.640816Z","iopub.execute_input":"2025-09-20T14:00:56.64115Z","iopub.status.idle":"2025-09-20T14:00:56.646798Z","shell.execute_reply.started":"2025-09-20T14:00:56.641119Z","shell.execute_reply":"2025-09-20T14:00:56.645665Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def _plot_analysis(signal, analysis_results):\n    \"\"\"\n    Helper function to visualize the results of the transit analysis.\n    \"\"\"\n    ingress = analysis_results['ingress']\n    egress = analysis_results['egress']\n    sigma_rel = analysis_results.get('sigma_rel', None)\n    debug = analysis_results['debug_info']\n\n    plt.style.use('seaborn-v0_8-whitegrid')\n    fig, ax = plt.subplots(figsize=(15, 9))\n\n    # Plot data points\n    ax.plot(signal, '.', color='gray', alpha=0.6, label='Signal Data')\n    ax.plot(debug['initial_oot_indices'],\n            signal[debug['initial_oot_indices']],\n            'o', color='skyblue', markersize=4,\n            label='Initial OOT Points')\n\n    # Plot analysis lines\n    ax.axhline(debug['global_baseline'], color='black', linestyle='--',\n               label=f'Global Baseline ({debug[\"global_baseline\"]:.4f})')\n    ax.axhline(debug['detection_threshold'], color='red', linestyle=':',\n               label=f'Detection Threshold ({debug[\"detection_threshold\"]:.4f})')\n\n    # Mark ingress/egress\n    if ingress is not None:\n        ax.axvline(ingress, color='green', linestyle='-', lw=2,\n                   label=f'Ingress: {ingress}')\n        ax.plot(ingress, signal[ingress], 'P', color='green',\n                markersize=12, markeredgecolor='black')\n\n    if egress is not None:\n        ax.axvline(egress, color='purple', linestyle='-', lw=2,\n                   label=f'Egress: {egress}')\n        ax.plot(egress, signal[egress], 'P', color='purple',\n                markersize=12, markeredgecolor='black')\n\n    title = \"Robust Transit Detection\"\n    if sigma_rel is not None and not np.isnan(sigma_rel):\n        title += f\" | σ_rel = {sigma_rel:.4e}\"\n    ax.set_title(title, fontsize=18)\n\n    ax.set_xlabel(\"Time Step / Index\", fontsize=12)\n    ax.set_ylabel(\"Normalized Flux\", fontsize=12)\n    ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.1), ncol=3)\n    ax.invert_yaxis()\n    plt.tight_layout()\n    plt.show()\n\n\ndef find_transit_points_robust(signal, initial_oot_window_size=60,\n                               sigma_threshold=2.0, consecutive_points=3,\n                               plot_results=False):\n    \"\"\"\n    Finds ingress/egress, computes baseline and relative sigma (uncertainty).\n    Returns NaN if sigma not computable.\n    \"\"\"\n    if not isinstance(signal, np.ndarray):\n        signal = np.array(signal)\n\n    # --- 1. Global Stats ---\n    min_idx = np.argmin(signal)\n    half_window = initial_oot_window_size // 2\n    win_start = max(0, min_idx - half_window)\n    win_end = min(len(signal)-1, min_idx + half_window)\n\n    oot_indices = np.concatenate([np.arange(0, win_start),\n                                  np.arange(win_end, len(signal))])\n    oot_indices = oot_indices[oot_indices < len(signal)]  # safety clamp\n\n    if len(oot_indices) < 10:\n        global_baseline = np.mean(signal)\n        global_sigma = np.std(signal)\n    else:\n        global_baseline = np.mean(signal[oot_indices])\n        global_sigma = np.std(signal[oot_indices])\n\n    detection_threshold = global_baseline - sigma_threshold * global_sigma\n    if detection_threshold < np.min(signal):\n        detection_threshold = global_baseline\n\n    # --- 2. Ingress & Egress detection ---\n    ingress_idx = None\n    for i in range(len(signal) - consecutive_points + 1):\n        if np.all(signal[i:i+consecutive_points] < detection_threshold):\n            ingress_idx = i\n            break\n\n    egress_idx = None\n    for i in range(len(signal)-1, consecutive_points-2, -1):\n        if np.all(signal[i-consecutive_points+1:i+1] < detection_threshold):\n            egress_idx = i\n            break\n\n    if ingress_idx is not None:\n        ingress_idx = min(max(0, ingress_idx), len(signal)-1)\n    if egress_idx is not None:\n        egress_idx = min(max(0, egress_idx), len(signal)-1)\n\n    # --- 3. Build OOT/IN ---\n    oot, inn = None, None\n    if ingress_idx is not None and egress_idx is not None and ingress_idx < egress_idx:\n        oot = np.concatenate((signal[:ingress_idx], signal[egress_idx:]))\n        inn = signal[ingress_idx:egress_idx]\n\n    # --- 4. Compute sigma ---\n    sigma_rel = np.nan\n    if oot is not None and inn is not None and len(oot) > 1 and len(inn) > 1:\n        var_oot = np.nanvar(oot, ddof=1)\n        var_in  = np.nanvar(inn, ddof=1)\n        n_oot, n_in = len(oot), len(inn)\n        oot_mean = np.nanmean(oot)\n\n        if np.isfinite(var_oot) and np.isfinite(var_in) and np.isfinite(oot_mean) and oot_mean > 0:\n            sigma_rel = np.sqrt(var_oot/n_oot + var_in/n_in) / oot_mean\n\n    # --- Package results ---\n    results = {\n        'ingress': ingress_idx,\n        'egress': egress_idx,\n        'global_baseline': global_baseline,\n        'sigma_rel': sigma_rel,\n        'debug_info': {\n            'min_idx': min_idx,\n            'initial_oot_indices': oot_indices,\n            'global_baseline': global_baseline,\n            'global_sigma': global_sigma,\n            'detection_threshold': detection_threshold,\n        }\n    }\n\n    if plot_results:\n        _plot_analysis(signal, results)\n\n    return results\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:56.64794Z","iopub.execute_input":"2025-09-20T14:00:56.648405Z","iopub.status.idle":"2025-09-20T14:00:56.672954Z","shell.execute_reply.started":"2025-09-20T14:00:56.648373Z","shell.execute_reply":"2025-09-20T14:00:56.671817Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#out folder and axis info\nOF =  '/kaggle/input/ariel-data-challenge-2025/'\nAI = '/kaggle/input/ariel-data-challenge-2025/axis_info.parquet'\n\naxis_info = pd.read_parquet(AI)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:56.675036Z","iopub.execute_input":"2025-09-20T14:00:56.675528Z","iopub.status.idle":"2025-09-20T14:00:56.722696Z","shell.execute_reply.started":"2025-09-20T14:00:56.67549Z","shell.execute_reply":"2025-09-20T14:00:56.721515Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Index File Created ","metadata":{}},{"cell_type":"code","source":"files  = glob.glob(os.path.join(OF,MODEE,'*')) #evrything inside the Folder means subfolder here\n\n\n\nidlist = [] #index list\nfor f in files:\n    index = int(f.split('/')[-1])\n    idlist.append(index)\n\nidlist.sort()\npids = idlist\npids = np.array(pids).reshape(-1,1)\npids = pd.DataFrame(pids,columns=['planet_id'])\npids.to_csv('planet_ids_info.csv',index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:56.723584Z","iopub.execute_input":"2025-09-20T14:00:56.723847Z","iopub.status.idle":"2025-09-20T14:00:56.7341Z","shell.execute_reply.started":"2025-09-20T14:00:56.723827Z","shell.execute_reply":"2025-09-20T14:00:56.73305Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 2. SET CONFIGURATIONS\nPROCESSING_FLAGS = {\n    'DO_MASK': True, 'DO_THE_NL_CORR': False, 'DO_DARK': True, \n    'DO_FLAT': True, 'TIME_BINNING': True\n}\nINSTRUMENT_CONFIGS = {\n    'AIRS': {\n        'id': 'AIRS-CH0',\n        'shape': (32, 356),\n        'cut_inf': 39,\n        'cut_sup': 321,\n        'time_bin_factor': 30,\n        'dt_calculator': lambda sig, ax_info: (d := ax_info['AIRS-CH0-integration_time'].dropna().values, d.__setitem__(slice(1, None, 2), d[1::2] + 0.1), d)[-1]\n    },\n    'FGS': {\n        'id': 'FGS1',\n        'shape': (32, 32),\n        'time_bin_factor': 30 * 12,\n        'dt_calculator': lambda sig, ax_info: (d := np.ones(len(sig)) * 0.1, d.__setitem__(slice(1, None, 2), d[1::2] + 0.1), d)[-1]\n    }\n}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:56.735257Z","iopub.execute_input":"2025-09-20T14:00:56.735621Z","iopub.status.idle":"2025-09-20T14:00:56.752891Z","shell.execute_reply.started":"2025-09-20T14:00:56.73559Z","shell.execute_reply":"2025-09-20T14:00:56.751753Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# =================================================================================\n# CORRECTED DATA PROCESSING FUNCTIONS\n# =================================================================================\n\ndef ADC_convert(signal, gain=0.4369, offset=-1000):\n    \"\"\"The Analog-to-Digital Conversion (adc) is performed by the detector to convert\n    the pixel voltage into an integer number. Since we are using the same conversion number\n    this year, we have simply hard-coded it inside. \"\"\"\n    signal = signal.astype(np.float64)\n    signal /= gain\n    signal += offset\n    return signal\n\ndef mask_hot_dead(signal, dead, dark):\n    hot = sigma_clip(dark, sigma=5, maxiters=5).mask\n    hot = np.tile(hot, (signal.shape[0], 1, 1))\n    dead = np.tile(dead, (signal.shape[0], 1, 1))\n    signal = np.ma.masked_where(dead, signal)\n    signal = np.ma.masked_where(hot, signal)\n    return signal\n\ndef apply_linear_corr(linear_corr,clean_signal):\n    linear_corr = np.flip(linear_corr, axis=0)\n    for x, y in itertools.product(\n                range(clean_signal.shape[1]), range(clean_signal.shape[2])\n            ):\n        poli = np.poly1d(linear_corr[:, x, y])\n        clean_signal[:, x, y] = poli(clean_signal[:, x, y])\n    return clean_signal\n\ndef clean_dark(signal, dead, dark, dt):\n    dark = np.ma.masked_where(dead, dark)\n    dark = np.tile(dark, (signal.shape[0], 1, 1))\n    signal -= dark * dt[:, np.newaxis, np.newaxis]\n    return signal\n\n### --- FIX #1 APPLIED HERE --- ###\ndef get_cds(signal):\n    \"\"\"\n    Performs Correlated Double Sampling on a 3D signal array.\n    Shape is assumed to be (time, height, width).\n    \"\"\"\n    # Correctly slices along the FIRST (time) axis using 3 indices\n    cds = signal[1::2, :, :] - signal[::2, :, :]\n    return cds\n\n### --- FIX #2 APPLIED HERE --- ###\ndef bin_obs(cds_signal, binning):\n    \"\"\"\n    Bins a 3D signal array along its first axis (time).\n    Shape is assumed to be (frames, height, width).\n    \"\"\"\n    n_frames, height, width = cds_signal.shape\n    n_binned_frames = n_frames // binning\n    # Trim the signal so its length is a multiple of the binning factor\n    trimmed_signal = cds_signal[:n_binned_frames * binning]\n    # Reshape and average over the new binning axis\n    binned_signal = trimmed_signal.reshape(n_binned_frames, binning, height, width).mean(axis=1)\n    return binned_signal\n\n### --- FIX #3 APPLIED HERE --- ###\ndef correct_flat_field(flat, dead, signal):\n    \"\"\"\n    Applies flat-field correction.\n    This corrected version assumes all inputs use a consistent (height, width) shape.\n    \"\"\"\n    flat_masked = np.ma.masked_where(dead, flat)\n    flat_tiled = np.tile(flat_masked, (signal.shape[0], 1, 1))\n    signal_corrected = signal / flat_tiled\n    return signal_corrected","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:56.754057Z","iopub.execute_input":"2025-09-20T14:00:56.754433Z","iopub.status.idle":"2025-09-20T14:00:56.782146Z","shell.execute_reply.started":"2025-09-20T14:00:56.754399Z","shell.execute_reply":"2025-09-20T14:00:56.78109Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def process_instrument(idx, path_folder, config, flags, axis_info):\n    \"\"\"\n    Loads, cleans, and processes all signal files for a specific instrument and index.\n    \"\"\"\n    instrument_id = config['id']\n    calib_path = os.path.join(path_folder, MODEE , f\"{idx}/{instrument_id}_calibration_0\")\n    cut_slice = slice(config.get('cut_inf'), config.get('cut_sup'))\n\n    # Load calibration files once per call\n    flat = pd.read_parquet(os.path.join(calib_path, 'flat.parquet')).values.reshape(config['shape'])[..., cut_slice]\n    dark = pd.read_parquet(os.path.join(calib_path, 'dark.parquet')).values.reshape(config['shape'])[..., cut_slice]\n    dead = pd.read_parquet(os.path.join(calib_path, 'dead.parquet')).values.reshape(config['shape'])[..., cut_slice]\n\n    signal_files = sorted(glob.glob(os.path.join(path_folder, MODEE ,f\"{idx}/{instrument_id}_signal_*.parquet\")))\n    \n    processed_signals = []\n    for sig_path in signal_files:\n        df = pd.read_parquet(sig_path)\n        sig = ADC_convert(df.values.astype(np.float64).reshape((-1,) + config['shape']))\n        sig = sig[..., cut_slice]\n\n        if flags['DO_MASK']:\n            sig = mask_hot_dead(sig, dead, dark)\n        if flags['DO_THE_NL_CORR']:\n            linear_corr = pd.read_parquet(os.path.join(calib_path, 'linear_corr.parquet')).values.reshape((6,) + config['shape'])[:, cut_slice]\n            sig = apply_linear_corr(linear_corr, sig)\n        if flags['DO_DARK']:\n            dt = config['dt_calculator'](sig, axis_info)\n            sig = clean_dark(sig, dead, dark, dt)\n\n        cds = get_cds(sig)\n        if flags['TIME_BINNING']:\n            cds = bin_obs(cds, config['time_bin_factor'])\n        if flags['DO_FLAT']:\n            cds = correct_flat_field(flat, dead, cds)\n            \n        processed_signals.append(cds)\n        \n    return processed_signals\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:56.78344Z","iopub.execute_input":"2025-09-20T14:00:56.783784Z","iopub.status.idle":"2025-09-20T14:00:56.809856Z","shell.execute_reply.started":"2025-09-20T14:00:56.783738Z","shell.execute_reply":"2025-09-20T14:00:56.808789Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom pqdm.threads import pqdm  # Use pqdm.threads if your task is I/O-bound\n\n\ndef process_single_id(indx):\n    \"\"\"\n    Processes a single instrument ID to calculate:\n      - White-light transit depth\n      - White-light relative sigma (uncertainty)\n\n    Returns a dictionary with keys:\n        'white_light_depth'\n        'white_light_sigma'\n    \"\"\"\n    signal = process_instrument(indx, OF, INSTRUMENT_CONFIGS['AIRS'],\n                                PROCESSING_FLAGS, axis_info)\n    dc = {}\n\n    # Case A: multiple sensor traces\n    if len(signal) < 187:\n        temp_depths, temp_sigmas = [], []\n        for k in range(len(signal)):\n            sig = np.mean(signal[k], axis=1)  # collapse to white-light curve\n            sig = np.mean(sig,axis=1)\n            results = find_transit_points_robust(sig)\n            ing, eg = results['ingress'], results['egress']\n            baseline, sigma_rel = results['global_baseline'], results['sigma_rel']\n\n            if ing is not None and eg is not None and ing < eg:\n                flat_bottom = np.mean(sig[ing:eg])\n                depth = baseline - flat_bottom\n                depth /= baseline\n            else:\n                depth = np.nan\n\n            temp_depths.append(depth)\n            temp_sigmas.append(sigma_rel)\n\n        dc['white_light_depth'] = np.nanmean(temp_depths)\n        dc['white_light_sigma'] = np.nanmean(temp_sigmas)\n\n    # Case B: already averaged signal\n    else:\n        sig = np.mean(signal, axis=1)  # collapse to white-light curve\n        sig = np.mean(signal, axis=1)  # collapse to white-light curve\n        \n        results = find_transit_points_robust(sig)\n        ing, eg = results['ingress'], results['egress']\n        baseline, sigma_rel = results['global_baseline'], results['sigma_rel']\n\n        if ing is not None and eg is not None and ing < eg:\n            flat_bottom = np.mean(sig[ing:eg])\n            depth = baseline - flat_bottom\n            depth /= baseline\n        else:\n            depth = np.nan\n\n        dc['white_light_depth'] = depth\n        dc['white_light_sigma'] = sigma_rel\n\n    return dc\n\n\n# --- Parallel execution ---\ndt = pqdm(idlist[:], process_single_id, n_jobs=4)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:00:56.81084Z","iopub.execute_input":"2025-09-20T14:00:56.811194Z","iopub.status.idle":"2025-09-20T14:01:09.464942Z","shell.execute_reply.started":"2025-09-20T14:00:56.811159Z","shell.execute_reply":"2025-09-20T14:01:09.463699Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dt = pd.DataFrame(dt)\nsigma = dt[['white_light_sigma']]\ndt = dt.drop(['white_light_sigma'],axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.469289Z","iopub.execute_input":"2025-09-20T14:01:09.469689Z","iopub.status.idle":"2025-09-20T14:01:09.478651Z","shell.execute_reply.started":"2025-09-20T14:01:09.469655Z","shell.execute_reply":"2025-09-20T14:01:09.477517Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#note this for TRAIN\ninfo = pd.read_csv(\"/kaggle/input/ariel-data-challenge-2025/test_star_info.csv\")\ninfo = info[['Rs','i']]\ntrain = pd.concat([dt,info],axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.479748Z","iopub.execute_input":"2025-09-20T14:01:09.480094Z","iopub.status.idle":"2025-09-20T14:01:09.507821Z","shell.execute_reply.started":"2025-09-20T14:01:09.480062Z","shell.execute_reply":"2025-09-20T14:01:09.506723Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.to_csv('test_model.csv',index=False)\nsigma.to_csv('sigma_planets.csv',index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.508813Z","iopub.execute_input":"2025-09-20T14:01:09.509116Z","iopub.status.idle":"2025-09-20T14:01:09.531155Z","shell.execute_reply.started":"2025-09-20T14:01:09.50909Z","shell.execute_reply":"2025-09-20T14:01:09.529917Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## PHASE 2","metadata":{}},{"cell_type":"code","source":"IN = pd.read_csv(\"/kaggle/working/test_model.csv\")\nIN = IN.fillna(0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.532714Z","iopub.execute_input":"2025-09-20T14:01:09.533036Z","iopub.status.idle":"2025-09-20T14:01:09.552231Z","shell.execute_reply.started":"2025-09-20T14:01:09.533Z","shell.execute_reply":"2025-09-20T14:01:09.551144Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"scaler = joblib.load(\"/kaggle/input/train-data-check-points-1/scaler_inp.pkl\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.553222Z","iopub.execute_input":"2025-09-20T14:01:09.553595Z","iopub.status.idle":"2025-09-20T14:01:09.564379Z","shell.execute_reply.started":"2025-09-20T14:01:09.553566Z","shell.execute_reply":"2025-09-20T14:01:09.563441Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IN_scaled = scaler.transform(IN)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.56551Z","iopub.execute_input":"2025-09-20T14:01:09.565814Z","iopub.status.idle":"2025-09-20T14:01:09.581402Z","shell.execute_reply.started":"2025-09-20T14:01:09.565789Z","shell.execute_reply":"2025-09-20T14:01:09.580155Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IN_scaled","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.582721Z","iopub.execute_input":"2025-09-20T14:01:09.583017Z","iopub.status.idle":"2025-09-20T14:01:09.603984Z","shell.execute_reply.started":"2025-09-20T14:01:09.582986Z","shell.execute_reply":"2025-09-20T14:01:09.60262Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ---------------------------\n# Residual Block\n# ---------------------------\nclass ResidualBlock(nn.Module):\n    def __init__(self, dim):\n        super(ResidualBlock, self).__init__()\n        # Two fully connected layers, both keep dimension = dim\n        self.fc1 = nn.Linear(dim, dim)\n        self.fc2 = nn.Linear(dim, dim)\n        # Batch normalization helps stabilize training\n        self.bn1 = nn.BatchNorm1d(dim)\n        self.bn2 = nn.BatchNorm1d(dim)\n\n    def forward(self, x):\n        # Save input for skip connection\n        residual = x\n        \n        # First linear transformation + ReLU\n        out = F.relu(self.bn1(self.fc1(x)))\n        # Second linear transformation\n        out = self.bn2(self.fc2(out))\n        \n        # Add skip connection (same dimension: dim)\n        out = out + residual\n        \n        # Final ReLU\n        out = F.relu(out)\n        return out\n\n\n# ---------------------------\n# Residual MLP Model\n# ---------------------------\nclass ResidualMLP(nn.Module):\n    def __init__(self, input_dim=3, hidden_dim=128, output_dim=1, num_blocks=6):\n        super(ResidualMLP, self).__init__()\n        \n        # Step 1: Project input (3 features) into hidden_dim (128)\n        self.fc_in = nn.Linear(input_dim, hidden_dim)\n        \n        # Step 2: Stack of residual blocks, all working in hidden_dim space\n        self.blocks = nn.Sequential(\n            *[ResidualBlock(hidden_dim) for _ in range(num_blocks)]\n        )\n        \n        # Step 3: Projection from hidden_dim (128) to smaller dimension (64)\n        self.fc_mid = nn.Linear(hidden_dim, hidden_dim // 2)\n        \n        # Step 4: Final output layer (64 → 1)\n        self.fc_out = nn.Linear(hidden_dim // 2, output_dim)\n\n    def forward(self, x):\n        # Project 3 → 128\n        x = F.relu(self.fc_in(x))\n        \n        # Pass through residual blocks (still 128)\n        x = self.blocks(x)\n        \n        # Reduce dimension 128 → 64\n        x = F.relu(self.fc_mid(x))\n        \n        # Final prediction 64 → 1\n        x = self.fc_out(x)\n        return x\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.605075Z","iopub.execute_input":"2025-09-20T14:01:09.605453Z","iopub.status.idle":"2025-09-20T14:01:09.622167Z","shell.execute_reply.started":"2025-09-20T14:01:09.605419Z","shell.execute_reply":"2025-09-20T14:01:09.620936Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Recreate the same model structure\nmodel = ResidualMLP(input_dim=3, hidden_dim=128, output_dim=1, num_blocks=6)\n\n# Load weights\nmodel.load_state_dict(torch.load(\"/kaggle/input/train-data-check-points-1/residual_mlp4.pth\"))\n\n\nmodel = model.double() #float 64\n\n\n# Switch to evaluation mode\nmodel.eval()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.623723Z","iopub.execute_input":"2025-09-20T14:01:09.624109Z","iopub.status.idle":"2025-09-20T14:01:09.671495Z","shell.execute_reply.started":"2025-09-20T14:01:09.624081Z","shell.execute_reply":"2025-09-20T14:01:09.670546Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample =  torch.tensor(IN_scaled,dtype=torch.float64)\nwith torch.no_grad():\n    pred = model(sample)\npred/=100","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.67243Z","iopub.execute_input":"2025-09-20T14:01:09.672662Z","iopub.status.idle":"2025-09-20T14:01:09.681046Z","shell.execute_reply.started":"2025-09-20T14:01:09.672644Z","shell.execute_reply":"2025-09-20T14:01:09.680105Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cols = pred.repeat(1, 283)\ntemp_df = pd.DataFrame(cols.numpy(), columns=[f\"wl_{i}\" for i in range(283)])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.6822Z","iopub.execute_input":"2025-09-20T14:01:09.682575Z","iopub.status.idle":"2025-09-20T14:01:09.698465Z","shell.execute_reply.started":"2025-09-20T14:01:09.68254Z","shell.execute_reply":"2025-09-20T14:01:09.697269Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#handle sigma \nfixed_sigma = 0.0026\nsigma_cols = [f'sigma_{j+1}' for j in range(283)]\n\n## 1. Create the Empty DataFrame\n\nimport pandas as pd\nimport numpy as np\n\n# Define the dimensions\nnum_rows = len(temp_df)\nnum_cols = 283\n\n# Create the empty DataFrame\nsigma_df = pd.DataFrame(index=range(num_rows), columns=sigma_cols)\nsigma_df[:] = fixed_sigma","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.699541Z","iopub.execute_input":"2025-09-20T14:01:09.699888Z","iopub.status.idle":"2025-09-20T14:01:09.726652Z","shell.execute_reply.started":"2025-09-20T14:01:09.699853Z","shell.execute_reply":"2025-09-20T14:01:09.725523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pids = pd.read_csv(\"/kaggle/working/planet_ids_info.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.727706Z","iopub.execute_input":"2025-09-20T14:01:09.727972Z","iopub.status.idle":"2025-09-20T14:01:09.749098Z","shell.execute_reply.started":"2025-09-20T14:01:09.727951Z","shell.execute_reply":"2025-09-20T14:01:09.748232Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.concat([pids,temp_df,sigma_df],axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.75079Z","iopub.execute_input":"2025-09-20T14:01:09.751129Z","iopub.status.idle":"2025-09-20T14:01:09.766586Z","shell.execute_reply.started":"2025-09-20T14:01:09.751095Z","shell.execute_reply":"2025-09-20T14:01:09.765504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.767745Z","iopub.execute_input":"2025-09-20T14:01:09.76808Z","iopub.status.idle":"2025-09-20T14:01:09.80178Z","shell.execute_reply.started":"2025-09-20T14:01:09.768047Z","shell.execute_reply":"2025-09-20T14:01:09.800919Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.to_csv('submission.csv',index=False) #File create","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-20T14:01:09.802564Z","iopub.execute_input":"2025-09-20T14:01:09.802805Z","iopub.status.idle":"2025-09-20T14:01:09.824378Z","shell.execute_reply.started":"2025-09-20T14:01:09.802785Z","shell.execute_reply":"2025-09-20T14:01:09.823318Z"}},"outputs":[],"execution_count":null}]}