{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#https://umrs.org.ua/activities/conferences/hmt-2025/abstract-guidelines/\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import sklearn\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Material and mold constants\n",
    "MOLD_DIAMETER_MM = 20\n",
    "MAX_THEORETICAL_DENSITY = 5.43  # g/cm³ for TiN\n",
    "mold_area_mm2 = 3.14 * MOLD_DIAMETER_MM * MOLD_DIAMETER_MM / 4\n",
    "\n",
    "def calculate_relative_density(\n",
    "        travel,\n",
    "        weight,  # in grams\n",
    "        measuredDensity,  # in g/cm^3\n",
    "        totalTravel,\n",
    "        maxTemperature):\n",
    "    \n",
    "    # Calculate final sample dimensions from measured density\n",
    "    final_volume_cm3 = weight / measuredDensity\n",
    "    final_volume_mm3 = final_volume_cm3 * 1000\n",
    "    final_height_mm = final_volume_mm3 / mold_area_mm2\n",
    "    \n",
    "    # Calculate initial height (before sintering started)\n",
    "    initial_height_mm = (totalTravel / 1000) + final_height_mm\n",
    "    \n",
    "    # Calculate current height based on piston travel\n",
    "    current_height_mm = initial_height_mm - (travel / 1000)\n",
    "    \n",
    "    # Calculate current volume and density\n",
    "    current_volume_mm3 = mold_area_mm2 * current_height_mm\n",
    "    current_volume_cm3 = current_volume_mm3 / 1000\n",
    "    current_density_g_cm3 = weight / current_volume_cm3\n",
    "    \n",
    "    # Convert to relative density (percentage of theoretical maximum)\n",
    "    relative_density_percent = (current_density_g_cm3 / MAX_THEORETICAL_DENSITY) * 100\n",
    "    \n",
    "    return relative_density_percent\n",
    "\n",
    "\n",
    "def calculate_density_for_series(travel, series):\n",
    "    total_travel = series['TravelRelativeTempCorrected'].max() - series['TravelRelativeTempCorrected'].min()\n",
    "    max_temp = series['Pyrometer'].max()\n",
    "    \n",
    "    return calculate_relative_density(\n",
    "        travel,\n",
    "        series.attrs['weight'],\n",
    "        series.attrs['measuredDensity'],\n",
    "        total_travel,\n",
    "        max_temp\n",
    "    )\n",
    "\n",
    "\n",
    "def calculate_densityForVirtualExperiment(\n",
    "        travel,\n",
    "        weight,  # in grams\n",
    "        relative_start_density,  # in %\n",
    "    ):\n",
    "    # Convert relative density to absolute density\n",
    "    absolute_start_density_g_cm3 = (relative_start_density / 100) * MAX_THEORETICAL_DENSITY\n",
    "    \n",
    "    # Calculate initial sample dimensions from starting density\n",
    "    initial_volume_cm3 = weight / absolute_start_density_g_cm3\n",
    "    initial_volume_mm3 = initial_volume_cm3 * 1000\n",
    "    initial_height_mm = initial_volume_mm3 / mold_area_mm2\n",
    "    \n",
    "    # Calculate current height after piston travel\n",
    "    current_height_mm = initial_height_mm - (travel / 1000)\n",
    "    \n",
    "    # Calculate current volume and density\n",
    "    current_volume_mm3 = mold_area_mm2 * current_height_mm\n",
    "    current_volume_cm3 = current_volume_mm3 / 1000\n",
    "    current_density_g_cm3 = weight / current_volume_cm3\n",
    "    \n",
    "    # Convert to relative density (percentage of theoretical maximum)\n",
    "    relative_density_percent = (current_density_g_cm3 / MAX_THEORETICAL_DENSITY) * 100\n",
    "    \n",
    "    return relative_density_percent\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def filter_data(df):\n",
    "    # Convert time to timedelta format\n",
    "    df['P.Zeit'] = pd.to_timedelta(df['P.Zeit'])\n",
    "    \n",
    "    # Filter out low temperature and low current readings\n",
    "    df = df[df['Pyrometer'] > 500].copy()\n",
    "    df = df[df['I RMS'] > 0.2].copy()\n",
    "    \n",
    "    # Calculate relative piston travel in micrometers\n",
    "    min_piston_travel = df['Abs Piston Tra.'].min()\n",
    "    df['TravelRelative'] = ((df['Abs Piston Tra.'] - min_piston_travel) * 1000).astype(int)\n",
    "    \n",
    "    # Smooth the travel data using cumulative maximum\n",
    "    df['TravelRelativeCorrected'] = np.maximum.accumulate(df['TravelRelative'])\n",
    "    df['TravelRelativeCorrected'] = df['TravelRelativeCorrected'].rolling(window=10).mean()\n",
    "    df.loc[pd.isnull(df['TravelRelativeCorrected']), 'TravelRelativeCorrected'] = 0\n",
    "    \n",
    "    # Apply thermal expansion correction (1.241 μm/°C)\n",
    "    min_temperature = df['Pyrometer'].min()\n",
    "    thermal_expansion_coefficient = 1.241  # μm/°C\n",
    "    temperature_delta = df['Pyrometer'] - min_temperature\n",
    "    df['TravelRelativeTempCorrected'] = df['TravelRelativeCorrected'] + (temperature_delta * thermal_expansion_coefficient)\n",
    "    \n",
    "    # Convert time to seconds from start\n",
    "    df['seconds'] = df['P.Zeit'].dt.total_seconds().astype(int)\n",
    "    min_seconds = df['seconds'].min()\n",
    "    df['seconds'] = df['seconds'] - min_seconds + 1\n",
    "    df = df.drop(columns=['P.Zeit'])\n",
    "    \n",
    "    # Downsample: keep every 10th row to reduce data size\n",
    "    df = df.iloc[::10]\n",
    "    \n",
    "    # Calculate original travel delta for comparison\n",
    "    df['TravelDeltaOriginal'] = df['Abs Piston Tra.'] - df['Abs Piston Tra.'].shift(1)\n",
    "    \n",
    "    # Calculate shifted values for next time step prediction\n",
    "    df['TravelRelativeCorrectedShifted'] = df['TravelRelativeCorrected'].shift(-1)\n",
    "    df['TravelRelativeCorrectedShifted'] = df['TravelRelativeCorrectedShifted'].fillna(0)\n",
    "    df['TravelRelativeTempCorrectedShifted'] = df['TravelRelativeTempCorrected'].shift(-1)\n",
    "    df['PyrometerShifted'] = df['Pyrometer'].shift(-1)\n",
    "    \n",
    "    # Calculate travel deltas (densification rates)\n",
    "    df['TravelDelta'] = df['TravelRelativeTempCorrectedShifted'] - df['TravelRelativeTempCorrected']\n",
    "    df['TravelDelta2'] = df['TravelRelativeCorrectedShifted'] - df['TravelRelativeCorrected']\n",
    "    df.loc[pd.isnull(df['TravelDelta']), 'TravelDelta'] = 0\n",
    "    \n",
    "    # Calculate relative density\n",
    "    df['Density'] = calculate_density_for_series(df['TravelRelativeTempCorrected'], df)\n",
    "    \n",
    "    # Remove last row (has no valid shifted values)\n",
    "    df = df.drop(df.index[-1])\n",
    "    \n",
    "    return df\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load experimental data into a dictionary\n",
    "experiments = {\n",
    "    '100_1500_32_ann': {\n",
    "        'file': 'TiN-Starck-0/1483.csv',\n",
    "        'measuredDensity': 4.92,\n",
    "        'weight': 6.5\n",
    "    },\n",
    "    '100_1500_32': {\n",
    "        'file': 'TiN-Starck-0/1500.csv',\n",
    "        'measuredDensity': 4.94,\n",
    "        'weight': 6.5\n",
    "    },\n",
    "    '100_1500_50': {\n",
    "        'file': 'TiN-Starck-0/1471.csv',\n",
    "        'measuredDensity': 5.12,\n",
    "        'weight': 6.47\n",
    "    },\n",
    "    '100_1500_70': {\n",
    "        'file': 'TiN-Starck-0/1499.csv',\n",
    "        'measuredDensity': 5.12,\n",
    "        'weight': 6.5\n",
    "    },\n",
    "    '200_1500_32': {\n",
    "        'file': 'TiN-Starck-0/1460.csv',\n",
    "        'measuredDensity': 4.94,\n",
    "        'weight': 6.5\n",
    "    },\n",
    "    '200_1600_50': {\n",
    "        'file': 'TiN-Starck-0/1459.csv',\n",
    "        'measuredDensity': 5.11,\n",
    "        'weight': 6.5\n",
    "    },\n",
    "    '200_1500_70': {\n",
    "        'file': 'TiN-Starck-0/1468.csv',\n",
    "        'measuredDensity': 5.12,\n",
    "        'weight': 6.2\n",
    "    },\n",
    "    '200_1500_70_noBn': {\n",
    "        'file': 'TiN-Starck-0/1469.csv',\n",
    "        'measuredDensity': 4.93,\n",
    "        'weight': 6.2\n",
    "    }\n",
    "}\n",
    "\n",
    "# Load and process all data\n",
    "data = {}\n",
    "original_data = {}\n",
    "for key, exp in experiments.items():\n",
    "    df = pd.read_csv(exp['file'], sep=';', decimal=',')\n",
    "    df.attrs['measuredDensity'] = exp['measuredDensity']\n",
    "    df.attrs['weight'] = exp['weight']\n",
    "    data[key] = filter_data(df)\n",
    "    original_data[key] = df.copy()\n",
    "    #print(data[key]['TravelRelativeCorrected'].max()- data[key]['TravelRelativeCorrected'].min())\n",
    "    #print(data[key]['TravelRelativeTempCorrected'].max()- data[key]['TravelRelativeTempCorrected'].min())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 133144 characters]",
      "text/plain": [
       "<Figure size 1200x800 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# write a code to plot time vs piston travel for all experiments in original_data\n",
    "plt.figure(figsize=(12, 8))\n",
    "for key, df in original_data.items():\n",
    "    plt.plot(df['P.Zeit'], df['Abs Piston Tra.'], label=key)\n",
    "plt.xlabel('Time')\n",
    "plt.ylabel('Piston Travel (mm)')\n",
    "plt.title('Time vs Piston Travel for All Experiments')\n",
    "plt.ylim(33, 44)\n",
    "plt.grid(True)\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 224376 characters]",
      "text/plain": [
       "<Figure size 2000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(40, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(20, 6))\n",
    "for key in data.keys():\n",
    "    ax1.plot(data[key]['Density'], data[key]['TravelDelta'], label=key)\n",
    "# Add color bar to show the color scale\n",
    "ax1.set_ylabel('Швидкість ущільнення')\n",
    "#ax1.set_ylim(400, 1000)\n",
    "ax1.set_xlim(30, 100)\n",
    "#ax1.set_title('title')\n",
    "ax1.set_xlabel('Відносна щільність')\n",
    "ax1.grid(True)\n",
    "plt.legend()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_data_Seconds(data, title):\n",
    "    setToPlot = data.copy()\n",
    "    plt.figure(figsize=(40, 6))\n",
    "    fig, ax1 = plt.subplots( figsize=(40, 6))\n",
    "    fig, ax2 = plt.subplots( figsize=(40, 6))\n",
    "    fig, ax3 = plt.subplots( figsize=(40, 6))\n",
    "    fig, ax4 = plt.subplots( figsize=(40, 6))\n",
    "    fig, ax5 = plt.subplots( figsize=(40, 6))\n",
    "    fig, ax6 = plt.subplots( figsize=(40, 6))\n",
    "    sc2 = ax1.plot(setToPlot['seconds'], setToPlot['Force'], color='black')\n",
    "    sc2 = ax2.plot(setToPlot['seconds'], setToPlot['TravelRelativeTempCorrected'], color='green')\n",
    "    sc2 = ax2.plot(setToPlot['seconds'], setToPlot['TravelRelative'], color='blue')\n",
    "    sc2 = ax3.plot(setToPlot['seconds'], setToPlot['Pyrometer'], color='orange')\n",
    "    sc2 = ax4.plot(setToPlot['seconds'], setToPlot['Power'], color='red')\n",
    "    sc2 = ax4.plot(setToPlot['seconds'], setToPlot['U RMS'], color='orange')\n",
    "    sc2 = ax4.plot(setToPlot['seconds'], setToPlot['I RMS'], color='purple')\n",
    "    sc2 = ax4.plot(setToPlot['seconds'], setToPlot['U RMS']/setToPlot['I RMS'], color='black')\n",
    "    sc2 = ax5.plot(setToPlot['seconds'], setToPlot['Density'], color='black')\n",
    "    sc2 = ax6.plot(setToPlot['seconds'], setToPlot['TravelDelta'], color='black')\n",
    "\n",
    "    ax4.set_ylim(0,10)\n",
    "    ax1.set_ylabel('Force')\n",
    "    ax2.set_ylabel('TravelRelativeTempCorrected')\n",
    "    ax3.set_ylabel('Pyrometer')\n",
    "    ax4.set_ylabel('Power')\n",
    "    ax5.set_ylabel('Density')\n",
    "    ax6.set_ylabel('TravelDelta')\n",
    "    ax1.grid(True)\n",
    "    ax2.grid(True)\n",
    "    ax3.grid(True)\n",
    "    ax4.grid(True)\n",
    "    ax5.grid(True)\n",
    "    ax6.grid(True)\n",
    "    ax1.set_title(title)\n",
    "    ax2.set_title(title)\n",
    "    ax3.set_title(title)\n",
    "    ax4.set_title(title)\n",
    "    ax5.set_title(title)\n",
    "    ax6.set_title(title)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 25232 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 79124 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48848 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 75716 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 50992 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 83292 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24452 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 79792 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 46404 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 68520 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 49752 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 87780 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 29164 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 77856 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 44764 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 72468 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48524 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 81296 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24552 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 75620 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48188 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 63652 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48844 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 77504 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24392 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 77652 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48032 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48340 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 49060 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 75304 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 29596 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 76080 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 50220 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 71164 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48468 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 75868 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 24540 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 74308 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 47340 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 57352 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 48008 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 74824 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 25544 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 74496 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 49020 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 57084 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 49168 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 75992 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for key in data.keys():\n",
    "    plot_data_Seconds(data[key], key)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 2000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 116220 characters]",
      "text/plain": [
       "<Figure size 3000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(20, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(30, 6))\n",
    "#sc = ax1.plot(data900['seconds'], data900['TravelDelta'], color='red')  \n",
    "#sc = ax1.plot(data1000['seconds'], data1000['TravelDelta'], color='green') \n",
    "sc = ax1.plot(data['100_1500_32']['seconds'], data['100_1500_32']['TravelDeltaOriginal']*1000, color='gray') \n",
    "sc = ax1.plot(data['100_1500_32']['seconds'], data['100_1500_32']['TravelDelta2'], color='red') \n",
    "ax1.set_ylabel('Швидкість ходу поршня, μm/с')\n",
    "#ax1.set_ylim(400, 1000)\n",
    "#ax1.set_xlim(300, 1400)\n",
    "ax1.set_title('Швидкість ходу поршня до і після усереднення')\n",
    "ax1.set_xlabel('час, с')\n",
    "ax1.grid(True)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_data_TravelDelta(data, title):\n",
    "    setToPlot = data.copy()\n",
    "\n",
    "    plt.figure(figsize=(40, 6))\n",
    "    fig, ax1 = plt.subplots( figsize=(40, 6))\n",
    "    sc = ax1.plot(setToPlot['Pyrometer'], setToPlot['TravelDelta'], color='red')  \n",
    "    ax1.set_ylabel('TravelDelta')\n",
    "    ax1.set_title(title)\n",
    "    ax1.set_xlabel('Pyrometer')\n",
    "    ax1.grid(True)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 76904 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_data_TravelDelta(data['100_1500_32'], 'data100_1500_32')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kernel: 1**2 * RBF(length_scale=1) -> test MSE: 1309.642096\n",
      "Kernel: 1**2 * Matern(length_scale=1, nu=1.5) -> test MSE: 634.860565\n",
      "Kernel: 1**2 * Matern(length_scale=1, nu=1.5) -> test MSE: 634.860565\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\gaussian_process\\_gpr.py:663: ConvergenceWarning: lbfgs failed to converge after 12 iteration(s) (status=2):\n",
      "ABNORMAL: \n",
      "\n",
      "You might also want to scale the data as shown in:\n",
      "    https://scikit-learn.org/stable/modules/preprocessing.html\n",
      "  _check_optimize_result(\"lbfgs\", opt_res)\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kernel: 1**2 * RationalQuadratic(alpha=0.1, length_scale=1) -> test MSE: 1310.007490\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\gaussian_process\\kernels.py:450: ConvergenceWarning: The optimal value found for dimension 0 of parameter k2__periodicity is close to the specified upper bound 1000.0. Increasing the bound and calling fit again may find a better value.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Kernel: 1**2 * ExpSineSquared(length_scale=1, periodicity=3) -> test MSE: 1308.997298\n",
      "Kernel: 1**2 * DotProduct(sigma_0=1) -> test MSE: 4410.157241\n",
      "Best kernel selected: 1**2 * Matern(length_scale=1, nu=1.5) with MSE 634.860565\n",
      "Mean Squared Error (best model on test set): 634.860565\n",
      "Kernel: 1**2 * DotProduct(sigma_0=1) -> test MSE: 4410.157241\n",
      "Best kernel selected: 1**2 * Matern(length_scale=1, nu=1.5) with MSE 634.860565\n",
      "Mean Squared Error (best model on test set): 634.860565\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\gaussian_process\\kernels.py:440: ConvergenceWarning: The optimal value found for dimension 0 of parameter k2__sigma_0 is close to the specified lower bound 1e-05. Decreasing the bound and calling fit again may find a better value.\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "from sklearn.gaussian_process import GaussianProcessRegressor\n",
    "from sklearn.gaussian_process.kernels import RBF, Matern, RationalQuadratic, ExpSineSquared, DotProduct, ConstantKernel as C\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import mean_squared_error\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.compose import TransformedTargetRegressor\n",
    "\n",
    "# Concatenate all experiments into a single dataset\n",
    "D = pd.concat([data[key] for key in data.keys()], axis=0)\n",
    "\n",
    "# Select features and target\n",
    "X = D[['seconds','TravelRelativeTempCorrected', 'Pyrometer','PyrometerShifted','Force','Density']].copy()\n",
    "y = D['TravelRelativeTempCorrectedShifted'].copy()\n",
    "\n",
    "# Drop rows with missing target or features\n",
    "mask = y.notna() & X.notnull().all(axis=1)\n",
    "X = X[mask]\n",
    "y = y[mask]\n",
    "\n",
    "# Split into train / test sets (hold out 20% for evaluation)\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42, shuffle=True)\n",
    "\n",
    "# Define candidate kernels with sensible bounds (scaling will help hyperparameters)\n",
    "kernels = [\n",
    "   C(1.0, (1e-6, 1e6)) * RBF(length_scale=1.0, length_scale_bounds=(1e-5, 1e5)),\n",
    "   C(1.0, (1e-6, 1e6)) * Matern(length_scale=1.0, length_scale_bounds=(1e-5,1e5), nu=1.5),\n",
    "   C(1.0, (1e-6, 1e6)) * RationalQuadratic(length_scale=1.0, length_scale_bounds=(1e-5,1e5), alpha=0.1),\n",
    "   C(1.0, (1e-6, 1e6)) * ExpSineSquared(length_scale=1.0, length_scale_bounds=(1e-5,1e5), periodicity=3.0, periodicity_bounds=(1e-3,1e3)),\n",
    "   C(1.0, (1e-6, 1e6)) * DotProduct(sigma_0=1.0)\n",
    "]\n",
    "\n",
    "# Helper wrapper to provide predict(..., return_std=True) using fitted scalers + GPR\n",
    "class WrappedGPR:\n",
    "    def __init__(self, x_scaler, gpr, y_scaler):\n",
    "        self.x_scaler = x_scaler\n",
    "        self.gpr = gpr\n",
    "        self.y_scaler = y_scaler\n",
    "    def predict(self, X, return_std=False):\n",
    "        import numpy as _np\n",
    "        X_arr = X.values if hasattr(X, 'values') else _np.asarray(X)\n",
    "        Xs = self.x_scaler.transform(X_arr)\n",
    "        if return_std:\n",
    "            y_pred_s, y_std_s = self.gpr.predict(Xs, return_std=True)\n",
    "            y_pred = self.y_scaler.inverse_transform(y_pred_s.reshape(-1,1)).ravel()\n",
    "            y_std = y_std_s * self.y_scaler.scale_[0]\n",
    "            return y_pred, y_std\n",
    "        else:\n",
    "            y_pred_s = self.gpr.predict(Xs)\n",
    "            y_pred = self.y_scaler.inverse_transform(y_pred_s.reshape(-1,1)).ravel()\n",
    "            return y_pred\n",
    "\n",
    "# Try each kernel inside a small pipeline that scales X and the target, evaluate on held-out test set\n",
    "best_mse = float('inf')\n",
    "best_kernel = None\n",
    "best_wrapped = None\n",
    "results = []\n",
    "# Keep optimizer restarts moderate for better tuning without huge runtime\n",
    "for k in kernels:\n",
    "    try:\n",
    "        # Base GPR that will be trained on scaled inputs\n",
    "        gpr_base = GaussianProcessRegressor(kernel=k, n_restarts_optimizer=10, alpha=1e-3, random_state=42)\n",
    "        reg_pipeline = Pipeline([('scaler', StandardScaler()), ('gpr', gpr_base)])\n",
    "        # Transform target (scale) so optimizer sees normalized y\n",
    "        model = TransformedTargetRegressor(regressor=reg_pipeline, transformer=StandardScaler())\n",
    "        model.fit(X_train, y_train)\n",
    "        # Get predictions on raw X_test (model handles transforms)\n",
    "        y_pred_k = model.predict(X_test)\n",
    "        mse_k = mean_squared_error(y_test, y_pred_k)\n",
    "        results.append((k, mse_k))\n",
    "        print(f'Kernel: {k} -> test MSE: {mse_k:.6f}')\n",
    "        if mse_k < best_mse:\n",
    "            best_mse = mse_k\n",
    "            best_kernel = k\n",
    "            # extract fitted components to build wrapper that supports return_std\n",
    "            fitted_x_scaler = model.regressor_.named_steps['scaler']\n",
    "            fitted_gpr = model.regressor_.named_steps['gpr']\n",
    "            fitted_y_scaler = model.transformer_\n",
    "            best_wrapped = WrappedGPR(fitted_x_scaler, fitted_gpr, fitted_y_scaler)\n",
    "    except Exception as e:\n",
    "        print(f'Kernel training failed for {k}: {e}')\n",
    "\n",
    "if best_wrapped is None:\n",
    "    raise RuntimeError('All kernel fits failed — check data or reduce kernel complexity')\n",
    "\n",
    "# Expose the wrapped model as `gpr` for downstream code (supports return_std)\n",
    "gpr = best_wrapped\n",
    "print(f'Best kernel selected: {best_kernel} with MSE {best_mse:.6f}')\n",
    "\n",
    "# Predictions and evaluation (for downstream plotting) — use wrapper to get mean\n",
    "y_pred = gpr.predict(X_test)\n",
    "mse = mean_squared_error(y_test, y_pred)\n",
    "print(f'Mean Squared Error (best model on test set): {mse:.6f}')\n",
    "\n",
    "# Reset indices so plotting code downstream works as expected\n",
    "X_test = X_test.reset_index(drop=True)\n",
    "y_test = y_test.reset_index(drop=True)\n",
    "y_pred = pd.Series(y_pred)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 121200 characters]",
      "text/plain": [
       "<Figure size 1500x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(15, 6))\n",
    "for key in data.keys():\n",
    "    ax1.plot(data[key]['seconds'], data[key]['TravelRelativeTempCorrectedShifted'], color='grey')\n",
    "sc = ax1.plot(X_test['seconds'], y_pred, color='red', linestyle='None', marker='o', markersize=4)\n",
    "ax1.set_title('Поріваняння передбаченого моделлю ходу поршня з реальними даними')\n",
    "ax1.set_xlabel('час, с')\n",
    "ax1.set_ylabel('хід поршня, μм')\n",
    "ax1.grid(True)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "def calculate_TargetDensificationRateValue(value):\n",
    "    value = value / 100\n",
    "    if value < 0.30:\n",
    "        return 10\n",
    "    elif 0.30 <= value < 0.50:\n",
    "        # Лінійне зростання від 0 до 450\n",
    "        return ((value - 0.30) / (0.50 - 0.30) * 450)+10\n",
    "    elif 0.50 <= value < 0.70:\n",
    "        # постійне ущільнення\n",
    "        return 450\n",
    "    elif 0.70 <= value < 0.85:\n",
    "        return 200\n",
    "    elif 0.85 <= value < 0.97:\n",
    "        # Лінійне зменшення від 200 до 0\n",
    "        return (0.97 - value) / (0.97 - 0.85) * 200\n",
    "    else:\n",
    "        return 0\n",
    "\n",
    "def calculate_TargetDensificationRate(column):\n",
    "    result = []\n",
    "    for value in column:\n",
    "        result.append(calculate_TargetDensificationRateValue(value))\n",
    "    return pd.Series(result, index=column.index)\n",
    "\n",
    "def find_closest_index(column, target_value):\n",
    "    squared_diff = (column - target_value) ** 2\n",
    "    return squared_diff.idxmin()\n",
    "\n",
    "#calulate_TargetDensificationRate(0.45)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 20596 characters]",
      "text/plain": [
       "<Figure size 1500x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot target densification rate vs density for values from 30 to 100\n",
    "plt.figure(figsize=(15, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(15, 6))\n",
    "for density in range(30, 101):\n",
    "    target_rate = calculate_TargetDensificationRateValue(density)\n",
    "    ax1.plot(density, target_rate, color='red', marker='o')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting density: 37.11039854577653%\n",
      "Time: 21s\n",
      "Density: 37.11%\n",
      "Time: 31s\n",
      "Density: 37.49%\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 41s\n",
      "Density: 37.93%\n",
      "Time: 51s\n",
      "Density: 38.43%\n",
      "Time: 61s\n",
      "Density: 39.00%\n",
      "Time: 71s\n",
      "Density: 39.65%\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 81s\n",
      "Density: 40.39%\n",
      "Time: 91s\n",
      "Density: 41.26%\n",
      "Time: 101s\n",
      "Density: 42.31%\n",
      "Time: 111s\n",
      "Density: 43.61%\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 121s\n",
      "Density: 45.28%\n",
      "Time: 131s\n",
      "Density: 47.36%\n",
      "Time: 141s\n",
      "Density: 49.95%\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 151s\n",
      "Density: 53.31%\n",
      "Time: 161s\n",
      "Density: 57.55%\n",
      "Time: 171s\n",
      "Density: 62.71%\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time: 181s\n",
      "Density: 69.17%\n",
      "Time: 191s\n",
      "Density: 77.51%\n",
      "Time: 201s\n",
      "Density: 88.71%\n",
      "Time: 211s\n",
      "Density: 104.54%\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n",
      "c:\\Users\\arros\\miniconda3\\envs\\SPS\\Lib\\site-packages\\sklearn\\utils\\validation.py:2749: UserWarning: X does not have valid feature names, but StandardScaler was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>seconds</th>\n",
       "      <th>TravelRelativeTempCorrected</th>\n",
       "      <th>Pyrometer</th>\n",
       "      <th>PyrometerShifted</th>\n",
       "      <th>Force</th>\n",
       "      <th>Density</th>\n",
       "      <th>STD</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1.0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>501.0</td>\n",
       "      <td>541.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>21.0</td>\n",
       "      <td>99.774472</td>\n",
       "      <td>595.0</td>\n",
       "      <td>634.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>63.117483</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>31.0</td>\n",
       "      <td>212.452335</td>\n",
       "      <td>634.0</td>\n",
       "      <td>673.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>27.243071</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>41.0</td>\n",
       "      <td>337.399328</td>\n",
       "      <td>673.0</td>\n",
       "      <td>712.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>29.458555</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>51.0</td>\n",
       "      <td>475.311209</td>\n",
       "      <td>712.0</td>\n",
       "      <td>751.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>32.188364</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>61.0</td>\n",
       "      <td>627.412133</td>\n",
       "      <td>751.0</td>\n",
       "      <td>790.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>35.123225</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>71.0</td>\n",
       "      <td>796.170687</td>\n",
       "      <td>790.0</td>\n",
       "      <td>829.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>38.295459</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>81.0</td>\n",
       "      <td>986.003234</td>\n",
       "      <td>829.0</td>\n",
       "      <td>868.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>41.906813</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>91.0</td>\n",
       "      <td>1203.974278</td>\n",
       "      <td>868.0</td>\n",
       "      <td>907.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>46.208953</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>101.0</td>\n",
       "      <td>1460.118812</td>\n",
       "      <td>907.0</td>\n",
       "      <td>946.0</td>\n",
       "      <td>22.0</td>\n",
       "      <td>37.110399</td>\n",
       "      <td>51.536822</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   seconds  TravelRelativeTempCorrected  Pyrometer  PyrometerShifted  Force  \\\n",
       "0      1.0                     0.000000      501.0             541.0   22.0   \n",
       "1     21.0                    99.774472      595.0             634.0   22.0   \n",
       "2     31.0                   212.452335      634.0             673.0   22.0   \n",
       "3     41.0                   337.399328      673.0             712.0   22.0   \n",
       "4     51.0                   475.311209      712.0             751.0   22.0   \n",
       "5     61.0                   627.412133      751.0             790.0   22.0   \n",
       "6     71.0                   796.170687      790.0             829.0   22.0   \n",
       "7     81.0                   986.003234      829.0             868.0   22.0   \n",
       "8     91.0                  1203.974278      868.0             907.0   22.0   \n",
       "9    101.0                  1460.118812      907.0             946.0   22.0   \n",
       "\n",
       "     Density        STD  \n",
       "0  37.110399        NaN  \n",
       "1  37.110399  63.117483  \n",
       "2  37.110399  27.243071  \n",
       "3  37.110399  29.458555  \n",
       "4  37.110399  32.188364  \n",
       "5  37.110399  35.123225  \n",
       "6  37.110399  38.295459  \n",
       "7  37.110399  41.906813  \n",
       "8  37.110399  46.208953  \n",
       "9  37.110399  51.536822  "
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Virtual Experiment: Optimize Sintering Process\n",
    "# This code simulates a sintering process by iteratively predicting the optimal temperature\n",
    "# to achieve target densification rates at each time step\n",
    "\n",
    "# ============================================================================\n",
    "# Initial Setup\n",
    "# ============================================================================\n",
    "\n",
    "# Start from first data point of the reference experiment\n",
    "virtual_experiment_key = '200_1500_70'\n",
    "virtual_experiment_start_density = data[virtual_experiment_key]['Density'].iloc[0]\n",
    "print (f'Starting density: {virtual_experiment_start_density}%')\n",
    "virtual_experiment_weight = experiments[virtual_experiment_key]['weight']\n",
    "initial_state = data[virtual_experiment_key].head(1)\n",
    "prediction_features = initial_state[['seconds', 'TravelRelativeTempCorrected', 'Pyrometer', \n",
    "                                      'PyrometerShifted', 'Force', 'Density']]\n",
    "prediction_features = prediction_features.reset_index(drop=True)\n",
    "\n",
    "# Initialize simulation parameters\n",
    "current_time = prediction_features['seconds'].iloc[0]\n",
    "num_temperature_options = 60  # Number of temperature scenarios to evaluate at each step\n",
    "time_step = 10  # Seconds between predictions\n",
    "max_simulation_time = 1000  # Maximum simulation duration\n",
    "target_density = 96  # Target relative density percentage\n",
    "\n",
    "# Store the predicted sintering regime\n",
    "predicted_regime = prediction_features.copy()\n",
    "\n",
    "# Create multiple prediction scenarios (will be populated in loop)\n",
    "prediction_scenarios = pd.concat([predicted_regime] * num_temperature_options, ignore_index=True)\n",
    "\n",
    "# ============================================================================\n",
    "# Simulation Loop\n",
    "# ============================================================================\n",
    "\n",
    "is_heating = True\n",
    "current_density = 32  # Starting density percentage\n",
    "\n",
    "# Initialize prediction scenarios with different temperature options\n",
    "current_time += time_step\n",
    "for i in range(num_temperature_options):\n",
    "    prediction_scenarios.loc[i, 'seconds'] = current_time\n",
    "    # Temperature offset from -5 to +54 degrees relative to current temperature\n",
    "    prediction_scenarios.loc[i, 'PyrometerShifted'] = prediction_scenarios['PyrometerShifted'].iloc[i] + i - 5\n",
    "\n",
    "# Main simulation loop: continue until time limit or target density reached\n",
    "while current_time < max_simulation_time and current_density < target_density:\n",
    "    \n",
    "    # ========================================================================\n",
    "    # Step 1: Predict outcomes for all temperature scenarios\n",
    "    # ========================================================================\n",
    "    travel_predictions, prediction_std = gpr.predict(prediction_scenarios, return_std=True)\n",
    "    \n",
    "    # ========================================================================\n",
    "    # Step 2: Calculate densification rates for each scenario\n",
    "    # ========================================================================\n",
    "    current_travel = prediction_scenarios['TravelRelativeTempCorrected'].iloc[0]\n",
    "    densification_rates = (travel_predictions - current_travel) / time_step / 1000\n",
    "    \n",
    "    # Update current density based on predicted travel\n",
    "    current_density = calculate_densityForVirtualExperiment(current_travel, virtual_experiment_weight, virtual_experiment_start_density)\n",
    "    \n",
    "    # ========================================================================\n",
    "    # Step 3: Select best temperature option\n",
    "    # ========================================================================\n",
    "    # Calculate target densification rate for current density\n",
    "    target_rate = calculate_TargetDensificationRateValue(current_density)\n",
    "    #print(f'Target rate: {target_rate}')\n",
    "    \n",
    "    # Find which scenario gives densification rate closest to target\n",
    "    predicted_rates_series = pd.Series(travel_predictions - current_travel)\n",
    "    #print(predicted_rates_series)\n",
    "    best_scenario_index = find_closest_index(predicted_rates_series, target_rate)\n",
    "    \n",
    "    # ========================================================================\n",
    "    # Step 4: Update prediction scenarios for next time step\n",
    "    # ========================================================================\n",
    "    current_time += time_step\n",
    "    \n",
    "    for i in range(num_temperature_options):\n",
    "        prediction_scenarios.loc[i, 'seconds'] = current_time\n",
    "        prediction_scenarios.loc[i, 'TravelRelativeTempCorrected'] = travel_predictions[best_scenario_index]\n",
    "        prediction_scenarios.loc[i, 'Pyrometer'] = prediction_scenarios['PyrometerShifted'].iloc[best_scenario_index]\n",
    "        \n",
    "        # Generate temperature scenarios: heating up or cooling down\n",
    "        if is_heating:\n",
    "            # Temperature offset from -20 to +39 degrees\n",
    "            prediction_scenarios.loc[i, 'PyrometerShifted'] = \\\n",
    "                prediction_scenarios['PyrometerShifted'].iloc[best_scenario_index] + i - 20\n",
    "        else:\n",
    "            # Cool down by 30 degrees\n",
    "            prediction_scenarios.loc[i, 'PyrometerShifted'] = \\\n",
    "                prediction_scenarios['PyrometerShifted'].iloc[best_scenario_index] - 30\n",
    "    \n",
    "    # ========================================================================\n",
    "    # Step 5: Record the selected scenario in the regime\n",
    "    # ========================================================================\n",
    "    best_prediction = prediction_scenarios.iloc[best_scenario_index]\n",
    "    best_prediction_df = pd.DataFrame([best_prediction])\n",
    "    \n",
    "    predicted_regime = pd.concat([predicted_regime, best_prediction_df], ignore_index=True)\n",
    "    predicted_regime.at[predicted_regime.index[-1], 'STD'] = prediction_std[best_scenario_index]\n",
    "    \n",
    "    # Progress tracking\n",
    "    print(f'Time: {current_time}s')\n",
    "    print(f'Density: {current_density:.2f}%')\n",
    "\n",
    "# Display first few rows of the predicted regime\n",
    "predicted_regime.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-20.0, 45.0)"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 127948 characters]",
      "text/plain": [
       "<Figure size 1500x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(15, 6))\n",
    "#heating rate\n",
    "\n",
    "for key in data.keys():\n",
    "    if key == virtual_experiment_key:\n",
    "        ax1.plot(data[key]['seconds'], data[key]['PyrometerShifted'] - data[key]['Pyrometer'], color='green')\n",
    "    else:\n",
    "        ax1.plot(data[key]['seconds'], data[key]['PyrometerShifted'] - data[key]['Pyrometer'], color='gray')\n",
    "sc = ax1.plot(predicted_regime['seconds'], predicted_regime['PyrometerShifted'] - predicted_regime['Pyrometer'], color='red') \n",
    "ax1.set_title('Швидкість нагріву в віртуальному експерименті в порівнянні з реальним даними')\n",
    "ax1.set_xlabel('час в секундах')\n",
    "ax1.set_ylabel('Швидкість °C/c')\n",
    "ax1.set_ylim(-20, 45 )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'TravelDelta μm/s')"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 81800 characters]",
      "text/plain": [
       "<Figure size 2000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 72732 characters]",
      "text/plain": [
       "<Figure size 2000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(20, 6))\n",
    "fig, ax2 = plt.subplots( figsize=(20, 6))\n",
    "#heating rate\n",
    "\n",
    "ax1.plot(data[virtual_experiment_key]['seconds'], data[virtual_experiment_key]['Pyrometer'], color='green') \n",
    "ax1.plot(data[virtual_experiment_key]['seconds'], data[virtual_experiment_key]['PyrometerShifted'] , color='lime') \n",
    "ax1.plot(predicted_regime['seconds'], predicted_regime['Pyrometer'], color='red') \n",
    "ax1.plot(predicted_regime['seconds'], predicted_regime['PyrometerShifted'] , color='orange') \n",
    "\n",
    "\n",
    "ax2.plot(data[virtual_experiment_key]['seconds'], data[virtual_experiment_key]['TravelDelta'], color='gray')\n",
    "ax2.plot( predicted_regime['seconds'], predicted_regime['TravelRelativeTempCorrected'] - predicted_regime['TravelRelativeTempCorrected'].shift(1), color='red')\n",
    "ax2.plot( predicted_regime['seconds'], calculate_TargetDensificationRate(calculate_densityForVirtualExperiment(predicted_regime['TravelRelativeTempCorrected'], virtual_experiment_weight, virtual_experiment_start_density)), color='green')\n",
    "#ax1.set_title('Швидкість нагріву в віртуальному експерименті в порівнянні з реальним даними')\n",
    "ax1.set_xlabel('час в секундах')\n",
    "ax1.set_ylabel('temperature °C')\n",
    "ax2.set_ylabel('TravelDelta μm/s')\n",
    "#ax1.set_ylim(-20, 45 )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 68832 characters]",
      "text/plain": [
       "<Figure size 1500x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(15, 6))\n",
    "\n",
    "#densification rate\n",
    "sc = ax1.plot( calculate_densityForVirtualExperiment(predicted_regime['TravelRelativeTempCorrected'], virtual_experiment_weight, virtual_experiment_start_density), predicted_regime['TravelRelativeTempCorrected'] - predicted_regime['TravelRelativeTempCorrected'].shift(1), color='red')\n",
    "sc = ax1.plot( calculate_densityForVirtualExperiment(predicted_regime['TravelRelativeTempCorrected'], virtual_experiment_weight, virtual_experiment_start_density), calculate_TargetDensificationRate(calculate_densityForVirtualExperiment(predicted_regime['TravelRelativeTempCorrected'], virtual_experiment_weight, virtual_experiment_start_density)), color='green')\n",
    "sc = ax1.plot(data[virtual_experiment_key]['Density'], data[virtual_experiment_key]['TravelDelta'], color='grey')\n",
    "\n",
    "#sc = ax1.plot(calulate_densityForVirtualExperiment(newRegime['TravelRelativeTempCorrected'], 6.5, 48), newRegime['STD'], color='blue') \n",
    "\n",
    "#ax1.set_title('title')\n",
    "ax1.set_xlabel('Щільність')\n",
    "ax1.set_ylabel('Швидкість ущільнення')\n",
    "ax1.grid(True)\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 59708 characters]",
      "text/plain": [
       "<Figure size 1500x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(15, 6))\n",
    "\n",
    "#Temperature\n",
    "sc = ax1.plot(data[virtual_experiment_key]['seconds'], data[virtual_experiment_key]['Pyrometer'], color='grey')\n",
    "sc = ax1.plot(predicted_regime['seconds'], predicted_regime['Pyrometer'], color='red')\n",
    "\n",
    "ax1.set_title('Порівняння температури з єксперементальними даними')\n",
    "ax1.set_xlabel('Час, с')\n",
    "ax1.set_ylabel('Температура °C')\n",
    "ax1.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 32436 characters]",
      "text/plain": [
       "<Figure size 1500x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(15, 6))\n",
    "\n",
    "#Temperature\n",
    "sc = ax1.plot(data[virtual_experiment_key]['seconds'], data[virtual_experiment_key]['Force'], color='grey')\n",
    "sc = ax1.plot(predicted_regime['seconds'], predicted_regime['Force'], color='red')\n",
    "\n",
    "ax1.set_title('Порівняння зусилля з єксперементальними даними')\n",
    "ax1.set_xlabel('Час, с')\n",
    "ax1.set_ylabel('Температура °C')\n",
    "ax1.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1500x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 60112 characters]",
      "text/plain": [
       "<Figure size 1500x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(15, 6))\n",
    "\n",
    "sc = ax1.plot(data[virtual_experiment_key]['seconds'], data[virtual_experiment_key]['TravelRelativeTempCorrectedShifted'], color='grey') \n",
    "sc = ax1.plot(predicted_regime['seconds'], predicted_regime['TravelRelativeTempCorrected'], color='red') \n",
    " \n",
    "ax1.set_title('Порівняння ходу поршня з єкспериментальними даними')\n",
    "ax1.set_xlabel('час, с')\n",
    "ax1.set_ylabel('хід поршня, μм')\n",
    "ax1.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 62172 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(40, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(40, 6))\n",
    "\n",
    "sc = ax1.plot(data[virtual_experiment_key]['TravelRelativeTempCorrectedShifted'], data[virtual_experiment_key]['Pyrometer'], color='grey') \n",
    "sc = ax1.plot(predicted_regime['TravelRelativeTempCorrected'], predicted_regime['Pyrometer'], color='red') \n",
    " \n",
    "\n",
    "ax1.set_title('title')\n",
    "ax1.set_xlabel('Microns')\n",
    "ax1.set_ylabel('Pyrometer')\n",
    "ax1.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 4000x600 with 0 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 64784 characters]",
      "text/plain": [
       "<Figure size 4000x600 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(40, 6))\n",
    "fig, ax1 = plt.subplots( figsize=(40, 6))\n",
    "\n",
    "sc = ax1.plot(data[virtual_experiment_key]['seconds'], data[virtual_experiment_key]['Pyrometer'], color='grey') \n",
    "#sc = ax1.plot(dataN1100['seconds'], dataN1100['Pyrometer'], color='grey') \n",
    "sc = ax1.plot(predicted_regime['seconds'], predicted_regime['Pyrometer'], color='red') \n",
    " \n",
    "\n",
    "ax1.set_title('title')\n",
    "ax1.set_xlabel('seconds')\n",
    "ax1.set_ylabel('Pyrometer')\n",
    "ax1.grid(True)\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "SPS",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
