{ "cells": [ { "cell_type": "markdown", "id": "97e5f7cf", "metadata": {}, "source": [ "This notebook showcases a pipeline that uses ServiceX for data delivery to coffea with Dask scaling.\n", "It is based on [this CMS Open Data ttbar analysis](https://github.com/iris-hep/analysis-grand-challenge/tree/main/analyses/cms-open-data-ttbar) with significant simplifications." ] }, { "cell_type": "code", "execution_count": 1, "id": "c8dc945e-0f70-4542-8725-7fbfa7b47865", "metadata": {}, "outputs": [], "source": [ "import asyncio\n", "import time\n", "\n", "import awkward as ak\n", "from coffea.processor import servicex\n", "from func_adl import ObjectStream\n", "from func_adl_servicex import ServiceXSourceUpROOT\n", "import hist\n", "import matplotlib.pyplot as plt\n", "from servicex import ServiceXDataset" ] }, { "cell_type": "markdown", "id": "8d8fd413-6c3e-46a0-9945-75a4c1bc6725", "metadata": {}, "source": [ "Configuration options: enable / disable `dask` and the use of caching with `ServiceX` (to force re-running transforms)." ] }, { "cell_type": "code", "execution_count": 2, "id": "9900ed24-64ac-4661-aa31-0f4714c7db4e", "metadata": {}, "outputs": [], "source": [ "# enable Dask\n", "USE_DASK = True\n", "\n", "# ServiceX behavior: ignore cache with repeated queries\n", "SERVICEX_IGNORE_CACHE = True" ] }, { "cell_type": "markdown", "id": "545eacca-c610-4069-b96d-6c44d8083abf", "metadata": {}, "source": [ "The processor used here: select jets with $p_T > 25$ GeV and calculate $\\textrm{H}_\\textrm{T}^{\\textrm{had}}$ (scalar sum of jet $p_T$) as observable." ] }, { "cell_type": "code", "execution_count": 3, "id": "d4e60d23-795c-4417-86c6-1696be3b65ec", "metadata": {}, "outputs": [], "source": [ "class TtbarAnalysis(servicex.Analysis):\n", " def __init__(self):\n", " self.hist = hist.Hist.new.Reg(50, 0, 1000, name=\"ht\", label=\"HT\").Weight()\n", "\n", " def process(self, events):\n", " histogram = self.hist.copy()\n", " \n", " # select jets with pT > 25 GeV\n", " selected_jets = events.jet[events.jet.pt > 25]\n", "\n", " # use HT (scalar sum of jet pT) as observable\n", " ht = ak.sum(selected_jets.pt, axis=-1)\n", " histogram.fill(ht=ht, weight=1.0)\n", "\n", " return histogram\n", "\n", " def postprocess(self, accumulator):\n", " return accumulator" ] }, { "cell_type": "markdown", "id": "6702d39b-70b2-4252-a569-d9db01444469", "metadata": {}, "source": [ "Specify which data to process, using a small public file here taken from 2015 CMS Open Data." ] }, { "cell_type": "code", "execution_count": 4, "id": "34588fe7-67dd-4b87-9306-b05334fc86d4", "metadata": {}, "outputs": [], "source": [ "# input data to process\n", "fileset = {\n", " \"ttbar\": {\n", " \"files\": [\"https://xrootd-local.unl.edu:1094//store/user/AGC/datasets/RunIIFall15MiniAODv2/TT_TuneCUETP8M1_13TeV-powheg-pythia8/MINIAODSIM//PU25nsData2015v1_76X_mcRun2_asymptotic_v12_ext3-v1/00000/00DF0A73-17C2-E511-B086-E41D2D08DE30.root\"],\n", " \"metadata\": {}\n", " }\n", "}" ] }, { "cell_type": "markdown", "id": "1bbe9b7b-19dd-4945-92e8-1757bb1b6d73", "metadata": {}, "source": [ "Set up the query: only requesting specific columns here without any filtering applied." ] }, { "cell_type": "code", "execution_count": 5, "id": "13b93c01-24ae-49a3-a91b-3a432c7d2f2b", "metadata": {}, "outputs": [], "source": [ "def get_query(source: ObjectStream) -> ObjectStream:\n", " \"\"\"Query for event / column selection: no filter, select single jet column\n", " \"\"\"\n", " return source.Select(lambda e: {\"jet_pt\": e.jet_pt})" ] }, { "cell_type": "markdown", "id": "2b55e5ac-885f-455c-a742-b30b364559c3", "metadata": {}, "source": [ "The following cell is mostly boilerplate, which can hopefully be improved in the future." ] }, { "cell_type": "code", "execution_count": 6, "id": "4022b82b-1aee-43d8-8958-b6947e5ed975", "metadata": {}, "outputs": [], "source": [ "def make_datasource(fileset:dict, name: str, query: ObjectStream, ignore_cache: bool):\n", " \"\"\"Creates a ServiceX datasource for a particular Open Data file.\"\"\"\n", " datasets = [ServiceXDataset(fileset[name][\"files\"], backend_name=\"uproot\", ignore_cache=ignore_cache)]\n", " return servicex.DataSource(\n", " query=query, metadata=fileset[name][\"metadata\"], datasets=datasets\n", " )\n", "\n", "\n", "async def produce_all_histograms(fileset, query, procesor_class, use_dask=False, ignore_cache=False):\n", " \"\"\"Runs the histogram production, processing input files with ServiceX and\n", " producing histograms with coffea.\n", " \"\"\"\n", " # create the query\n", " ds = ServiceXSourceUpROOT(\"cernopendata://dummy\", \"events\", backend_name=\"uproot\")\n", " ds.return_qastle = True\n", " data_query = query(ds)\n", "\n", " # executor: local or Dask\n", " if not use_dask:\n", " executor = servicex.LocalExecutor()\n", " else:\n", " executor = servicex.DaskExecutor(client_addr=\"tls://localhost:8786\") # set up for coffea-casa\n", "\n", " datasources = [\n", " make_datasource(fileset, ds_name, data_query, ignore_cache=ignore_cache)\n", " for ds_name in fileset.keys()\n", " ]\n", "\n", " # create the analysis processor\n", " analysis_processor = procesor_class()\n", "\n", " async def run_updates_stream(accumulator_stream):\n", " \"\"\"Run to get the last item in the stream\"\"\"\n", " coffea_info = None\n", " try:\n", " async for coffea_info in accumulator_stream:\n", " pass\n", " except Exception as e:\n", " raise Exception(f\"Failure while processing {name}\") from e\n", " return coffea_info\n", "\n", " output = await asyncio.gather(\n", " *[\n", " run_updates_stream(executor.execute(analysis_processor, source))\n", " for source in datasources\n", " ]\n", " )\n", "\n", " return output" ] }, { "cell_type": "markdown", "id": "908d64f0-bbfa-4f75-9da4-9b5ee3e1745e", "metadata": {}, "source": [ "Execute everything: query `ServiceX`, which sends columns back to `coffea` processors asynchronously, collect the aggregated histogram built by `coffea`." ] }, { "cell_type": "code", "execution_count": 7, "id": "5b1d63a1-d9e5-4f23-a709-a73eeb0460ab", "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "[https://xrootd-loca...: 0%| | 0/9000000000.0 [00:00]" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "execution took 13.40 seconds\n" ] } ], "source": [ "t0 = time.time()\n", "\n", "output = await produce_all_histograms(\n", " fileset, get_query, TtbarAnalysis, use_dask=USE_DASK, ignore_cache=SERVICEX_IGNORE_CACHE\n", ")\n", "\n", "print(f\"execution took {time.time()-t0:.2f} seconds\")" ] }, { "cell_type": "code", "execution_count": 8, "id": "f9e969b9-9925-4d43-9d0f-201d1547681f", "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "output[0].plot(label=\"ttbar\")\n", "plt.legend();" ] } ], "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.9.12" } }, "nbformat": 4, "nbformat_minor": 5 }