{ "cells": [ { "cell_type": "markdown", "id": "a4e39ece", "metadata": {}, "source": [ "# Full Demo\n", "\n", "This notebooks demonstrates the comprehensive workflow how to use the framework `CHAMPPY` (Charging and Mobility Profiles in Python) to create mobility and charging profiles from your mobility data. " ] }, { "cell_type": "markdown", "id": "863fd041", "metadata": {}, "source": [ "## 1. Import Required Libraries\n", "Import all necessary libraries, including pandas, os and champpy." ] }, { "cell_type": "code", "execution_count": 1, "id": "e0c7272a", "metadata": {}, "outputs": [], "source": [ "import pandas as pd\n", "import os\n", "import champpy" ] }, { "cell_type": "markdown", "id": "2836d9f5", "metadata": {}, "source": [ "## 2. Load raw data and create raw mobility profiles\n", "Load the example logbooks and vehicles from csv files and create raw mobility profiles from it using the `MobProfiles` class. You can use your own data. Therefore you have to bring your data in the required format. Use the provided examples for logbooks and vehicles as a guide to get your data into the required format." ] }, { "cell_type": "code", "execution_count": 2, "id": "af4f6cdd", "metadata": {}, "outputs": [], "source": [ "# Load example raw logbook data from CSV\n", "base_dir = os.path.abspath(os.path.join(os.getcwd(), os.pardir))\n", "logbook_path = os.path.join(base_dir, \"data\", \"example1\", \"t_logbook.csv\")\n", "raw_logbook_df = pd.read_csv(logbook_path, parse_dates=[\"dep_dt\", \"arr_dt\"])\n", "\n", "# Load example raw vehicle data from CSV\n", "vehicle_path = os.path.join(base_dir, \"data\", \"example1\", \"t_vehicle.csv\")\n", "raw_vehicle_df = pd.read_csv(vehicle_path, parse_dates=[\"first_day\", \"last_day\"],date_format=\"%d-%b-%Y\")\n", "\n", "# Create raw mobility profiles\n", "raw_profiles = champpy.MobProfiles(input_logbooks_df=raw_logbook_df, input_vehicles_df=raw_vehicle_df)" ] }, { "cell_type": "markdown", "id": "63d7c8a9", "metadata": {}, "source": [ "## 3. Clean raw mobility profiles\n", "To prepare your data for the next steps, you must clean the data. The `MobProfilesCleaner` class is provided for this purpose. It can be initialized by different user parameters using the `UserParamsCleaning` data class. After the cleaning, a summary is provided showing which data has been changed." ] }, { "cell_type": "code", "execution_count": 3, "id": "0bb7f135", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2026-03-10 18:49:36 - INFO - champpy.core.mobility.mobility_cleaning] MobProfiles Cleaning Summary:\n", "[2026-03-10 18:49:36 - INFO - champpy.core.mobility.mobility_cleaning] Data has been converted to temporal resolution of 0.25 hours.\n", "[2026-03-10 18:49:36 - INFO - champpy.core.mobility.mobility_cleaning] Deleted journeys:\n", " - Due to distance issues: 285 journeys: id_journeys = [2429, 2434, 2438, 2442, 2453, ...]\n", " - Due to speed issues: 0 journeys: id_journeys = []\n", " - Due to duration issues: 0 journeys: id_journeys = []\n", "[2026-03-10 18:49:36 - INFO - champpy.core.mobility.mobility_cleaning] Modified journeys:\n", " - Due to distance issues: 5 journeys: id_journeys = [872, 941, 948, 961, 965]\n", " - Due to speed issues: 0 journeys: id_journeys = []\n", " - Due to duration issues: 0 journeys: id_journeys = []\n", " - Due to location issues: 3 journeys: id_journeys = [0, 1, 0]\n", "[2026-03-10 18:49:36 - INFO - champpy.core.mobility.mobility_cleaning] Check deleted_id_journeys and modified_id_journeys attribute for full list.\n" ] } ], "source": [ "# Initialize the data cleaner with user parameters\n", "user_params_cleaning = champpy.UserParamsCleaning(\n", " speed = champpy.LimitConfig(min_value=0.01, min_method=\"delete\", max_value=120.0, max_method=\"cap\"),\n", "\tduration = champpy.LimitConfig(min_value=0.25, min_method=\"delete\", max_value=8.0, max_method=\"cap\"),\n", "\tdistance = champpy.LimitConfig(min_value=0.5, min_method=\"delete\", max_value=500.0, max_method=\"cap\"),\n", "\ttemp_res = 0.25, # Temporal resolution in hours\n", "\tprint_summary = True\n", ")\n", "data_cleaner = champpy.MobProfilesCleaner(user_params=user_params_cleaning)\n", "\n", "# Apply data cleaner on your raw mobility profiles\n", "mob_profiles_cleaned = data_cleaner.clean(raw_profiles)" ] }, { "cell_type": "markdown", "id": "f49adbcf", "metadata": {}, "source": [ "If you want to further validate the cleaning of the profiles, you can plot the mobility profiles before and after the cleaning using the `MobPlotter` class as shown below:" ] }, { "cell_type": "code", "execution_count": 4, "id": "7bf7a903", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2026-03-10 18:49:47 - INFO - champpy.core.mobility.mobility_validation] Generate plot of mobility profiles\n", "[2026-03-10 18:49:47 - INFO - champpy.core.mobility.mobility_data] Extending MobProfiles\n", "[2026-03-10 18:49:47 - INFO - champpy.core.mobility.mobility_validation] Create plot of mobility characteristics\n", "[2026-03-10 18:49:48 - INFO - champpy.core.mobility.mobility_validation] Create plot of mobility histograms\n", "[2026-03-10 18:49:49 - INFO - champpy.core.mobility.mobility_validation] Create plot of location profile over the week\n" ] } ], "source": [ "# Create a copy of the cleaned mobility profiles and add the raw data for comparison using add_mob_data()\n", "mob_profiles_merged = mob_profiles_cleaned.copy()\n", "mob_profiles_merged.add_mob_profiles(raw_profiles, old_cluster_label=\"Raw Data\", new_cluster_label=\"Cleaned Data\")\n", "\n", "# Initialize the mobility plotter with user parameters for plotting\n", "user_params_plot = champpy.UserParamsMobPlotter(\n", " filename=\"demo02_validation_data_cleaning.html\",\n", " clustering =True,\n", " show=True,\n", " save_plot=True\n", ")\n", "\n", "# Create and instance of the mobility plotter and generate the plots for the merged mobility data\n", "mobplot = champpy.MobPlotter(user_params_plot)\n", "mobplot.plot_mob_profiles(mob_profiles_merged)" ] }, { "cell_type": "markdown", "id": "39f052f1", "metadata": {}, "source": [ "## 4. Parameterization\n", "Parameterize the model based on your cleaned mobility profiles. The parameterization is performed using the `Paramterizer` class. It must be initialized by user parameters using the `UserParamsParameterizer` data class:" ] }, { "cell_type": "code", "execution_count": 5, "id": "0a925b75", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2026-03-10 18:49:53 - INFO - champpy.core.mobility.parameterization] Starting parameterization of the mobility model.\n", "[2026-03-10 18:49:53 - INFO - champpy.core.mobility.mobility_data] Extending MobProfiles\n", "[2026-03-10 18:49:54 - INFO - champpy.core.mobility.mobility_data] Extending MobProfiles\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "d7811b3cf4654317a9131e2cf8ab87a4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n"
      ],
      "text/plain": []
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Define user params for the parameterization\n",
    "user_params = champpy.UserParamsParameterizer(\n",
    "    description=\"Example parameterization 1\", # Define a description for the parameter set\n",
    "    vehicle_type=\"Van\", # Type of vehicle the parameters apply to (e.g., \"Car\", \"Van\", \"Truck\")\n",
    "    temp_res = 0.25  # Temporal resolution in hours\n",
    ")\n",
    "# Create an instance of the Parameterizer\n",
    "example_parameterizer = champpy.Parameterizer(user_params)\n",
    "\n",
    "# calculate the model parameters based on the cleaned mobility profiles\n",
    "model_params = example_parameterizer.calc_params(mob_profiles_cleaned)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4ad7540b",
   "metadata": {},
   "source": [
    "## 5. Generate Mobility Profiles\n",
    "Using the `MobModel` and `UserParamsMobModel` to generate synthetic mobility profiles for a specified number of vehicles and date range. The model parameters generated in the previous step, serves as input to create the instance of `MobModel`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e2128099",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2026-03-10 18:50:00 - INFO - champpy.core.mobility.mobility_model] Start generating mobility profiles for 50 vehicles from 2025-01-01 01:00:00 to 2025-12-31 23:00:00\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "2899a1bc5aef48b685a0b6aaf1fb5c0f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Output()"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "
\n"
      ],
      "text/plain": []
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Generate synthetic mobility profiles\n",
    "mob_model = champpy.MobModel(model_params=model_params)\n",
    "user_params_mob = champpy.UserParamsMobModel(\n",
    "    number_vehicles=50,\n",
    "    start_date=pd.Timestamp(\"2025-01-01-00:00:00\"),\n",
    "    end_date=pd.Timestamp(\"2025-12-31-23:00:00\"),\n",
    ")\n",
    "mob_profiles = mob_model.generate_mob_profiles(user_params=user_params_mob)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "122e6214",
   "metadata": {},
   "source": [
    "## 6. Validate modeled mobility profiles\n",
    "Merge the modeled mobility profiles with the cleaned reference profiles. Use the classes `UserParamsMobPlotter` and `MobPlotter` to create an html file that contains several validation plots."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7c45cdcd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2026-03-10 18:50:04 - INFO - champpy.core.mobility.mobility_validation] Generate plot of mobility profiles\n",
      "[2026-03-10 18:50:04 - INFO - champpy.core.mobility.mobility_data] Extending MobProfiles\n",
      "[2026-03-10 18:50:05 - INFO - champpy.core.mobility.mobility_validation] Create plot of mobility characteristics\n",
      "[2026-03-10 18:50:09 - INFO - champpy.core.mobility.mobility_validation] Create plot of mobility histograms\n",
      "[2026-03-10 18:50:13 - INFO - champpy.core.mobility.mobility_validation] Create plot of location profile over the week\n"
     ]
    }
   ],
   "source": [
    "# Create a copy of the cleaned mobility profiles and add the modeld profiles for comparison using add_mob_data()\n",
    "mob_profiles_merged = mob_profiles_cleaned.copy()\n",
    "mob_profiles_merged.add_mob_profiles(mob_profiles, old_cluster_label=\"Ref\", new_cluster_label=\"Model\")\n",
    "\n",
    "# Initialize user parameters for plotting the mobiltiy profiles\n",
    "user_params_plot = champpy.UserParamsMobPlotter(\n",
    "    filename=\"demo02_mobility_profiles_validation_plot.html\",\n",
    "    clustering = True,\n",
    "    show=True,\n",
    "    save_plot=True\n",
    ")\n",
    "\n",
    "# Create instance of the mobility plotter\n",
    "mobplot = champpy.MobPlotter(user_params_plot)\n",
    "\n",
    "# Plot the mobility profiles for the merged data (ref + model)\n",
    "mobplot.plot_mob_profiles(mob_profiles_merged)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c80a10f9",
   "metadata": {},
   "source": [
    "## 7. Generate charging profiles\n",
    "Use classes`ChargeModel` and `UserParamsChargeModel` to generate synthetic charging profiles."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "e16b930d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2026-03-10 18:50:22 - INFO - champpy.core.mobility.mobility_data] Creating MobArray from MobProfiles\n",
      "[2026-03-10 18:50:22 - INFO - champpy.core.mobility.mobility_data] Extending MobProfiles\n",
      "[2026-03-10 18:50:24 - INFO - root] Generating charging profiles based on mobility data and user parameters...\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "9089083aa9f4474fa8f8e1321cda068a",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Output()"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "
\n"
      ],
      "text/plain": []
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Initilaize the charging model with the modeled mobility prfiles\n",
    "charging_model = champpy.ChargingModel(mob_profiles)\n",
    "\n",
    "# Define user parameters for the charging model\n",
    "user_params_charging = champpy.UserParamsChargingModel(\n",
    "    energy_consumption_kwh_per_km=[0.2],\n",
    "    battery_capacity_kwh=[50.0],\n",
    "    charging_power_max_kw=[11],\n",
    "    efficiency_charging=[0.9],\n",
    "    soc_min=[0.1],\n",
    "    soc_min_dep=[0.8],\n",
    "    soc_initial=1,\n",
    "    distribute_energy_consumption=True,\n",
    "    charging_locations=[1], \n",
    "    temp_res=0.25\n",
    ")\n",
    "\n",
    "# Generate charging profiles based on the mobility profiles and the user parameters for charging\n",
    "charging_profiles = charging_model.generate_charging_profiles(user_params=user_params_charging)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61d572ae",
   "metadata": {},
   "source": [
    "## 8. Validate charging profiles\n",
    "\n",
    "You can visulize the modeld charging profiles using the `ChargingPlotter` class. It must be initializes by different user parameters defined in the `UserParamsChargingPlotter` data class. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "803893a5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2026-03-10 18:50:29 - INFO - champpy.core.charging.charging_validation] Generate plot of charging profiles\n",
      "[2026-03-10 18:50:29 - INFO - champpy.core.charging.charging_validation] Create plot of charging characteristics\n",
      "[2026-03-10 18:50:38 - INFO - champpy.core.charging.charging_validation] Create plot of load profile over the course of a week\n"
     ]
    }
   ],
   "source": [
    "# Initialize user parameters for plotting the charging profiles\n",
    "user_params_plot = champpy.UserParamsChargingPlotter(\n",
    "    filename=\"demo02_charging_profiles_plot.html\",\n",
    "    show=True,\n",
    "    save_plot=True,\n",
    "    clustering=False\n",
    ")\n",
    "\n",
    "# Create an instance of the ChargingPlotter\n",
    "chargeplot = champpy.ChargingPlotter(user_params_plot)\n",
    "\n",
    "# Plot the charging profiles\n",
    "chargeplot.plot_charging_profiles(charging_profiles)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv (3.13.7)",
   "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.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}