{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "cfb9c989-bb26-47ac-92a6-857ee05993f6",
   "metadata": {},
   "source": [
    "# Roxie Api\n",
    "\n",
    "## General\n",
    "\n",
    "* Python access to roxie files\n",
    "* Manipulation of Input files\n",
    "* Parsing of Output files\n",
    "* Roxie execution\n",
    "\n",
    "## Use and Install\n",
    "\n",
    "* Two parts: [roxie-api](https://roxie-api.docs.cern.ch/), [roxie-interfaces](https://roxie-interfaces.docs.cern.ch/)\n",
    "* Available on pip\n",
    "* OR: Full docker package: \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57af300e-66bf-4b1f-850d-333681a1ed27",
   "metadata": {},
   "source": [
    "## Input file manipulation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "98d09440-63ed-40d2-a9b9-e90a2e2fc8fa",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import pathlib\n",
    "import tempfile\n",
    "\n",
    "from roxieapi.input.builder import RoxieInputBuilder\n",
    "\n",
    "folder = pathlib.Path(\"./examples\").absolute()\n",
    "datafile = \"dipole_iron.data\"\n",
    "\n",
    "rib = RoxieInputBuilder.from_datafile(folder / datafile)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "faf7b438-df2f-4b83-b211-c435682b6a84",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "rib.block"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c163ae02-6c21-4d40-bbc6-8c4133c6b589",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "rib.block[rib.block['no']==2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bf0dc6f1-d33f-499b-81c0-6218969899dd",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "rib.flags"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f71a9d49-8919-4df5-aa07-e62ae447ddb1",
   "metadata": {},
   "source": [
    "## Write the output file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "209a08a1-c50c-4666-b5cf-2db8d571c43e",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "tmp_file = folder / \"my_datafile.data\"\n",
    "rib.build(str(tmp_file))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03ecc41a-5d8b-4f68-a36b-e395b5be6668",
   "metadata": {},
   "source": [
    "# Executing Roxie\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "393cbe7a-6a42-40cc-86da-b386774d3e22",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import pathlib\n",
    "import tempfile\n",
    "\n",
    "from roxieapi.tool_adapter.RoxieToolAdapter import RestRoxieToolAdapter\n",
    "\n",
    "input_files = [\n",
    "    tmp_file,\n",
    "]\n",
    "\n",
    "runner = RestRoxieToolAdapter(\n",
    "    service_url=f\"http://roxie:8080\",\n",
    "    input_files=input_files,\n",
    ")\n",
    "\n",
    "result = runner.run()\n",
    "\n",
    "print(f\"Run executed with return code {result}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4a100094-9c2e-441e-9d40-4c7fb8dbc0a2",
   "metadata": {},
   "source": [
    "## Getting outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5284b20-8c89-4e06-a6cb-f05d28d03c22",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print(runner.output)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a4035a30-a505-45c3-926a-bc20b13ead32",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "runner.get_artefact_list()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "73328887-6368-49de-a1ae-1f876c18b4ad",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "output_folder = pathlib.Path(\"./outputs\").absolute()\n",
    "\n",
    "runner.download_artefacts(output_folder, \"*.xml\")\n",
    "runner.download_artefacts(output_folder, \"*.pdf\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3ff3e89-6237-47e3-8d2e-4fc904984c0f",
   "metadata": {},
   "source": [
    "# Output processing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8571bd28-67f2-4622-916e-dcc52b7a5f1a",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from roxieapi.output.plots import RoxiePlotOutputs\n",
    "\n",
    "plots = RoxiePlotOutputs(\n",
    "    output_folder/\"my_datafile.post.xml\", tmp_file\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b8182297-7c90-4ff5-8179-e80dc9b0e470",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "del plots.output.opt[1].step[1].eddyTimeSteps[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf3979be-98e6-4741-ae14-50731a8bc05f",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "plots.output_report()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebff1ddd-f814-41f2-b4a6-e4db97272a3a",
   "metadata": {},
   "source": [
    "## Custom Plots\n",
    "\n",
    "* Load data from xml file\n",
    "* Plot, using existing plots\n",
    "* custom, custom plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dd8d3e2e-4411-4061-884f-5e3035e7290a",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "ts = plots.output.find_transstep(1,1)\n",
    "ts.coilData"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "244500ce-c87b-4314-b96f-cdcbb9bdd298",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "from roxieapi.commons.roxie_constants import PlotLabels\n",
    "from roxieapi.commons.types import Plot2D, PlotLegend\n",
    "from roxieapi.output.plots import RoxiePlotOutputs\n",
    "\n",
    "for pl in PlotLabels.plot2D_desc:\n",
    "    lbl, desc = PlotLabels.lbl_desc_plot2D(pl)\n",
    "    print(f\"Coil plot {pl}, Label:  '{lbl}', Description: '{desc}'\")\n",
    "\n",
    "for pl in PlotLabels.plotMesh2D_desc:\n",
    "    lbl, desc = PlotLabels.lbl_desc_mesh2D(pl)\n",
    "    print(f\"Mesh plot {pl}, Label:  '{lbl}', Description: '{desc}'\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dff8bc86-4c48-4471-ae4b-03aaae027145",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "plot_created = Plot2D.create(\"My Plot2D\")\n",
    "plot_created.add_coilPlot(\"52\", harm_coil=1)\n",
    "\n",
    "figure = plots.plots2d.plot_xs(plot_created)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf0b14e8-7e33-4785-83ff-1b80b6ebfb7c",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "plot_created = Plot2D.create(\"My Plot2D\")\n",
    "plot_created.add_coilPlot(\"52\", harm_coil=1)\n",
    "plot_created.add_meshPlot(\"35\", legend=PlotLegend(\"e\", False, 0, 1))\n",
    "\n",
    "figure = plots.plots2d.plot_xs(plot_created)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13f24f6d-3db3-4f0a-a61d-b122b7159f12",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "ts.harmonicCoils[1].an\n",
    "ts.harmonicCoils[1].bn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21b4d30d-2b4a-49b0-b00a-75975e62f75b",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "# Your dictionaries\n",
    "an = ts.harmonicCoils[1].an\n",
    "bn = ts.harmonicCoils[1].bn\n",
    "\n",
    "# Collect all harmonic IDs except 1\n",
    "ids = sorted(i for i in (set(an.keys()) | set(bn.keys())) if i != 1)\n",
    "\n",
    "# Values aligned by harmonic ID\n",
    "an_vals = [an.get(i, 0) for i in ids]\n",
    "bn_vals = [bn.get(i, 0) for i in ids]\n",
    "\n",
    "# Bar positions\n",
    "x = np.arange(len(ids))\n",
    "width = 0.4\n",
    "\n",
    "# Plot\n",
    "plt.figure(figsize=(10, 5))\n",
    "plt.bar(x - width/2, an_vals, width=width, color='red', label='an')\n",
    "plt.bar(x + width/2, bn_vals, width=width, color='blue', label='bn')\n",
    "\n",
    "# Labels and styling\n",
    "plt.xticks(x, ids)\n",
    "plt.xlabel('Harmonic ID')\n",
    "plt.ylabel('Value')\n",
    "plt.title('Harmonic Coefficients (excluding ID 1)')\n",
    "plt.legend()\n",
    "plt.grid(axis='y', alpha=0.3)\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ee1ecad8-9443-42a6-8849-438344348f6e",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
