{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"input_collapsed": false
},
"source": [
"# Exporting Burst Data\n",
"\n",
"*This notebook is part of a [tutorial series](https://github.com/OpenSMFS/FRETBursts_notebooks) for the [FRETBursts](http://opensmfs.github.io/FRETBursts/) burst analysis software.*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> In this notebook, show a few example of how to export [FRETBursts](http://opensmfs.github.io/FRETBursts/) \n",
"> burst data to a file.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"Please cite FRETBursts in publications or presentations!\n",
"
"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Loading the software"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We start by loading **`FRETBursts`**:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" - Optimized (cython) burst search loaded.\n",
" - Optimized (cython) photon counting loaded.\n",
"--------------------------------------------------------------\n",
" You are running FRETBursts (version 0.7+46.ge31fadb.dirty).\n",
"\n",
" If you use this software please cite the following paper:\n",
"\n",
" FRETBursts: An Open Source Toolkit for Analysis of Freely-Diffusing Single-Molecule FRET\n",
" Ingargiola et al. (2016). http://dx.doi.org/10.1371/journal.pone.0160716 \n",
"\n",
"--------------------------------------------------------------\n"
]
}
],
"source": [
"from fretbursts import *"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"sns = init_notebook()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Downloading the data file"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The full list of smFRET measurements used in the [FRETBursts tutorials](https://github.com/OpenSMFS/FRETBursts_notebooks) \n",
"can be found on [Figshare](http://dx.doi.org/10.6084/m9.figshare.1456362).\n",
"\n",
"This is the file we will download:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"url = 'http://files.figshare.com/2182601/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"You can change the url variable above to download your own data file.\n",
"This is useful if you are executing FRETBursts online and you want to use\n",
"your own data file. See \n",
"First Steps.\n",
"
\n",
"\n",
"Here, we download the data file and put it in a folder named `data`, \n",
"inside the notebook folder:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"URL: http://files.figshare.com/2182601/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5\n",
"File: 0023uLRpitc_NTP_20dT_0.5GndCl.hdf5\n",
" \n",
"File already on disk: /home/paul/Disk/Python/OpenSMFS/FRETBursts_notebooks/notebooks/data/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5 \n",
"Delete it to re-download.\n"
]
}
],
"source": [
"download_file(url, save_dir='./data')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> **NOTE**: If you modified the `url` variable providing an invalid URL\n",
"> the previous command will fail. In this case, edit the cell containing \n",
"> the `url` and re-try the download."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Loading the data file"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here, we can directly define the file name to be loaded:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'./data/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"filename = \"./data/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5\"\n",
"filename"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's check that the file exists:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Perfect, file found!\n"
]
}
],
"source": [
"import os\n",
"if os.path.isfile(filename):\n",
" print(\"Perfect, file found!\")\n",
"else:\n",
" print(\"Sorry, file:\\n%s not found\" % filename)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"d = loader.photon_hdf5(filename)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# μs-ALEX parameters\n",
"\n",
"At this point, timestamps and detectors numbers are contained in the `ph_times_t` and `det_t` attributes of `d`. Let's print them:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"([array([ 146847, 188045, 294124, ..., 47999863658,\n",
" 47999877783, 47999955353])],\n",
" [array([0, 1, 1, ..., 1, 1, 0], dtype=uint32)])"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"d.ph_times_t, d.det_t"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We need to define some ALEX parameters: "
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"d.add(det_donor_accept = (0, 1), \n",
" alex_period = 4000,\n",
" offset = 700,\n",
" D_ON = (2180, 3900), \n",
" A_ON = (200, 1800))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here the parameters are:\n",
"\n",
"- `det_donor_accept`: donor and acceptor channels\n",
"- `alex_period`: length of excitation period (in timestamps units)\n",
"- `D_ON` and `A_ON`: donor and acceptor excitation windows\n",
"- `offset`: the offset between the start of alternation and start of timestamping \n",
" (see also [Definition of alternation periods](http://photon-hdf5.readthedocs.org/en/latest/phdata.html#definition-of-alternation-periods)).\n",
"\n",
"To check that the above parameters are correct, we need to plot the histogram of timestamps (modulo the alternation period) and superimpose the two excitation period definitions to it:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAzkAAAG8CAYAAAD98GtbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAACPFElEQVR4nOzdeXwTZf4H8M9M0iO9ixyVFqioLQoFyuFB4adYEMHSIlgUpFZEERFFYBdBlxVBDg9kpYggK8cWUbBFFhAErcAqq1D3VQSroshZpS1HSs8kTWZ+f5SMTZOWJE2aNnzerxemfeaZZ54nkzHz7XOMIMuyDCIiIiIiIi8heroCRERERERErsQgh4iIiIiIvAqDHCIiIiIi8ioMcoiIiIiIyKswyCEiIiIiIq/CIIeIiIiIiLwKgxwiIiIiIvIqDHKIiIiIiMirMMghIiIiIiKvovZ0BbyBLMuQJNnl5Yqi4JZyIcuQjdWA7IayHSAAEEQBsiTDszVxD7avKSsjQFD7AILg8qJdeR3KsoxqqRoyJJeU5wrmc+jNvL2NLbF9AkT4iD4Q7Lhm3fVdKIqCXccnopaJQY4LSJKMS5cqXFqmWi0iPDwQpaWVMBpde0Mk63WQj/0A+KgBtY9Ly3aEShQREuKP0lIdTFLzuelzFbaviRirgWojhNhuEPz8XVq0q69DnUmHIxfz4CP6wEf03LVnJqpEBIf4o6xUB8nkfZ9RwPvb2BLbVy1Vo1qqRvfr4uGvaviaded3YatWgVCpGOQQeSsGOdcytQ8EH1+PHV5QiRB8/SD4ShBayJezI9i+piEDQLXRY8d3ho/oA1+Vn6erAZVKhJ/KDwaVDFMz6l1yJW9vY0ttX7VU7ekqEJGX45wcIiIiIiLyKgxyiIiIiIjIqzDIISIiIiIir8Igh4iIiIiIvAqDHCIiIiIi8ioMcoiIiIiIyKswyCEiIiIiIq/CIIeIiIiIiLwKgxwiIiIiIvIqDHKIiIiIiMirMMghIiIiIiKvwiCHiIiIiIi8CoMcIiIiIiLyKmpPV4Bcy/TWHKC0xHpDSBhU0+c3eX2IiIiIiJqaQ0HOyZMnsW3bNhw4cABnzpyBXq9Hx44dcd999yE9PR0BAQEW+S9cuIAlS5Zg//79KCsrQ3R0NNLS0jB69Gib5e/YsQNr1qzB8ePHodFokJCQgBkzZiAyMtIqrzvLbtFKS4DLWk/XgoiIiIjIYxwKcrKzs/HBBx9g4MCBSEpKgo+PDw4ePIh//OMf2LVrFzZv3gx/f38AQGlpKcaOHYuioiKkp6cjKioKOTk5mDNnDoqLizFlyhSLsjds2ID58+ejV69emD17NrRaLdavX4/c3FxkZWWhXbt2Sl53lu01RAEIDgPKSgBJ9nRtiIiIiIiajENBzpAhQzBx4kSEhIQoaWPGjEGnTp2wcuVKZGdn45FHHgEArF69GqdPn0ZGRgbuvfdeAMDo0aMxadIkrFy5EikpKejQoQMAQKvVYsmSJejatSsyMzOhVtdUa8CAAUhNTcWyZcuwYMEC5ZjuLNtrBIdBNTcDprnPsmeHiIiIiK4pDi08EBcXZxHgmA0dOhQAcOzYMSVt+/btiIqKUoIQs/Hjx6O6uhq7du1S0nJyclBZWYm0tDQlCDEfr2/fvti1axcMBkOTlE22SR+8C+m9N2z/++BdT1ePiIiIiEjhkoUHioqKAADXXXcdAOD8+fM4d+4ckpKSrPLGx8dDEAQcOXJESTP/HB8fbzP/oUOHcOLECXTp0sWtZV+rpA/eBSrKbW8MDIL4yNM128tLm7ZiREREREROaHSQYzKZsGLFCqjVagwfPhzAn0FPRESEVX5fX1+Eh4ejsLBQSSsuLq43v3m+TFFREbp06eLWshtDrXbtatwqlWjxaovhjZesV1IruwwIgCDU1EkSALnW7wBgWDIf8vlCQBAhi0LDwYtQUwdJqPkZgggEBtVsqygHZEnJ43gbhVqv3reaOdvXNGSTCKhFiGoRggeuQ0eoIUKlFiGqRJeV2RiiKNR69Xx93MHb29gS2ydChAoi1Crxqt+drr4Gieja0egg59VXX8Xhw4fx/PPPo3PnzgAAnU4HoCbosMXPz0/JAwBVVVX15vfz87PI486ynSWKAsLDAxtVRn1CQjT1brtQUQqprMQiTRBq/iOqRISHB+KCSoQk/vk7AFyoLIOpsqIms2DeqYYYHAoAkMvLIMsSRFFESIgGJaIISRAgBocg7C9/BwCUvDkPUtllCJUVkN57o1YZwQh5aprdbQwM9Lc7b0vE9rmXbBAhVcnwCwuE4O+eujR0HTqiyigiyOCPAB9/+Kn8XFKmKwQGNZ+6uIu3t7Eltc/XJEBVLSEsPAAatX3XlquuQSK6djQqyFm6dCk2btyI1NRUTJo0SUk3r7BW31wXnU6H1q1bK79rNBolv3+dmxS9Xm+Rx51lO0uSZJSWVjaqjLpUqprgorS0CiaTZDOPySRBlmRAECGEhFpuCwyBVluh5JFNErTaij/3k+Wa4CYwWNlHCAyGmDYZAFC98jWgvBSmslJcfH3ulV4bGSZJQmlpTVBokiRAliHLJosepdp5Gm6jgMBAf1RU6GAyed8KcGxf05ANBkCvQ2VJBQQ/k0vLtuc6dITOqEN5uQ4mlQiDyvOfCVEUEBjkh4pyPSQvXYXR29vYEtunN+lRZdKhxLcSOnXD15Wrr8HaQkI07CEi8mJOBzkZGRlYuXIlRowYgXnz5kGo1RtgHgZWe9iYmV6vR0lJCfr06aOktW3bVskfHR1tkd88PM1cpjvLbgyj0bX/8zUzmaR6y5ZlADKAkFCIL2fYrJM5jyz/WUdZvvJFGBAE8cm/Wh2vJpP5nwSU1RrOJtfKExBUk8esoqzmQLXzNEi8ckzZ4S8vu+YReZzz7WsZmkf7ZEkCjBIkowRB1fTXoSOMJgkmowQJEkxoDp+JmnMoSd76GQW8v40tr33SlevAaJJgtPM6cNU1SETXDqeCnOXLl2P58uVITk7GokWLIIqWfwlp06YNIiIicPjwYat9Dx8+DFmWERcXp6TFxcVh06ZNyMvLswpE8vLyEBAQoAyFc2fZXq2spGY5aaBm3s7VmOfdNJBeN5CQ3nujZn5PRZnF8DXzfi4NPFy0EELLCJaosUxvzbGev2YWEgbV9PlNWh8iIiJyL4eDnOXLlyMjIwPDhw/H4sWLrQIcs6SkJPzzn//Enj17LJZ6Xrt2LdRqNYYNG6akJSYmYsGCBcjMzMTw4cOVpZ6PHj2K3NxcjBw50mJOjTvL9lqSXOt5OVcf0tCom3tZtg5AykstA5/AIKgefcb5Y5jVHnJn7km6gqvGkaK0hM+LIiIiuoY4FOR88MEHyMjIQPv27ZGQkIAdO3ZYbG/dujUSEhIAABMnTsTu3bsxc+ZM5OfnIyoqCjk5Odi7dy8mT56sPKwTAFq1aoVp06Zh4cKFSEtLQ0pKCrRaLdatW4fWrVtj6tSpFsdxZ9leJyTMOk2WAJ0OCHDxYgm2en9qBxDuCCYCgyFOrBlyp/QkmTkSwDQQLJEXEQUgOKzm57KSmuCfiIiIvI5DQc7Ro0cBAH/88QdmzZpltf22225TgpzQ0FBs3LgRS5cuxebNm1FeXo5OnTph7ty5GDNmjNW+6enpCA8Px9q1a7Fw4UJoNBr069cP06dPt5oz486yvY2tYTiyXgf52A9AIxdcqMtW749Vb4o5gKgoQ/XK11AiilcWMIDrhoeZh8tVlNX8bk8A01CwZEO9vUQOtsFV5ZCdgsOgmlszf80091n27hAREXkph4KcxYsXY/HixXbnb9u2LRYtWmR3/uTkZCQnJ3u8bHKdeuftXBnSJgmCsliBkqehYWZm5gDGlrrD5RwMYOxSXy9RrWF5koCapbc1gRDGTrLO21A5V2FPcMQAioiIiK5VjX5ODpFDag9pEwBRFGEqK60ZQmfm7DwZOxZLcDlzL5GtYXkCIAkCZEmCYHtv63LsHSpnz3vE+UZERER0jWKQQ02qdg+C+fkHF1+fW7NMdUPDzOrTwGpvDap7LGdd6SWy2WtSWY7aXVQ285iPby7H0Z4me4IjRwMoIiIiohaOQQ41Hw0MM3P7sWyxtRR2rW212ZyPtPpKEFVR3qhhco0Ojurmaahdyj5XH/YmBwUDz8xwtDkKu4Yl2qiPVT0+Wg2Ul0H29weEOqs9cnloIiKiaxKDHPI4ITDYdgeDO4aZOTKkzZ5AyB6yZF1OUIh99QIcG3ZWO4Cpr5fK0XbVc3y51hg8pwIWVw2nq6yo6TUz6ICrDwwkIiKiawCDHPI4ddrkJntSt11D2hwJrhrIKwQG18w5Mq8eV2sfpyb+2xq+V/f4DQUw9rTL2WFvjQlYGhqWaONYVgFVZfmf5YSE1/xsXh7a/BDcshLn6kZEREQtEoMcojpctfKYOm0yQkI0KC2tck0Q19DwvYYCmCvb7GmXzSFtjgyNczBgqV1ug/WxKKeegCo41Hp5aIuH4BIREdG1gkEOUXNkz7CzWly+JLSzQ/XsCVhcteiDOaCSZUCSgODQP7fZeghuQ+lERETkVRjkEDVHrpoP5Cg7eoQazZm2NdCzJFcbgKoqCLHdlOxcbICIiOjaxiCHqDlpiiCjAY4tw12Okjfn1cw5sqdXpjHPMfJU0EdEREQtEoMcombE5cPO3EmWIJVdrglA7Hj8jlNta4qgz7w4gRmXnSYiImrxGOQQkWPMwYUA69XjXNzb1CRBHxcnICIi8joMcojIIebAQ6USXbt6XFOruwiBedlpIiIiavEY5BDRNanukDRl2WkiIiJq8URPV4CIiIiIiMiVGOQQEREREZFXYZBDRERERERehUEOERERERF5FQY5RERERETkVRjkEBERERGRV2GQQ0REREREXoVBDhEREREReRU+DLQFMb01Bygt+TOhrKS+rERERERE1ywGOS1JaQmfyE5EREREdBUMcloiUQCCw/78PSSsvpxERERERNccBjktUXAYVHMzPF0LIiIiIqJmiQsPEBERERGRV2GQQ0REREREXoVBDhEREREReRXOySEiaoauX7UKqrJym9tMwUE499RTTVwjagjPFxFR88Igh4ioGVKVlUNVVubpapCdGjpfqrIyRL25RPn9Wg16zIGgDBmSLEGt1sAEEQgJg2r6fE9Xj4i8jMNBzqpVq5Cfn4/8/HwUFBQgMjISX375pc28sbGxDZb1/PPP4+mnn7Yrf25uLkJCQizSLly4gCVLlmD//v0oKytDdHQ00tLSMHr0aJtl7NixA2vWrMHx48eh0WiQkJCAGTNmIDIyssF6EhF5jCDAFBQEAFCVlwOy3CSHra9norncoDfbnpPa56tW0NMcAlZPv2fmQFCGDFGWAVEPQAAua2Ga+6xlZgY+RNRIDgc5b731FsLCwnDrrbei7Cr/03799ddtpi9fvhxnzpzBwIEDrbb16dPHZpCi0Wgsfi8tLcXYsWNRVFSE9PR0REVFIScnB3PmzEFxcTGmTJlikX/Dhg2YP38+evXqhdmzZ0Or1WL9+vXIzc1FVlYW2rVrd7WmExE1OVNQEAr+MgMAEPXmEqjKyqAqL3dpz0C7FSsh1vn/uTM35fbcRLvqRtvunhNBgBAWgrKJE+0qt7Fqn6+6bXVlkKqULQhQqQQEmWRAlht8D53tHWzonNVl1zkUBBiDAuFTof8zjQ+6JiIXczjI+eKLL9ChQwcAQFJSEiorK+vNm5KSYpVWWFiIWbNmoVu3bujSpYvV9g4dOtjcr67Vq1fj9OnTyMjIwL333gsAGD16NCZNmoSVK1ciJSVFqadWq8WSJUvQtWtXZGZmQq2uafaAAQOQmpqKZcuWYcGCBVdvPBGRE0xvzQFKS6CGhFuMVRAFEQIE54MTWa73ZtWZHhixvOGbX1NwsM0bdKubeDtuoF0+rMuOnhOxvAzXv/6mRf2boueibvnmINUVar+PoigAkgPBUwO9g7Y+P47Uue45tNhWXlOuKSgIPz07AfGZ2yHULbusxLG2EBHVw+Egxxw4OCs7OxuSJCE1NbXePAaDAQaDAUFX/idsy/bt2xEVFaUEOGbjx4/H3r17sWvXLky88pe7nJwcVFZWIi0tTQlwACAuLg59+/bFrl278PLLL8PX17dRbSMisqm05MpfqmWopWoIggABgkUWm3/1r8MUbPn/RPMNau2eHXtuSOv2AsC8T62b39rHPPfUUzZv0BsKWEzBwRZ1tOKiYV0N9pzULre0tE7d6w+oPD1Uz56eE+XzIQiQQkOAklK7e4ka6h282vtvPq9W9XHiHJqe/zt8VP6WaXOfZa8OEblEky48IMsytmzZAo1Gg6SkJJt5du/ejW3btsFkMiEsLAyDBg3C888/jzZt2ih5zp8/j3PnztksIz4+HoIg4MiRI0qa+ef4+Hib+Q8dOoQTJ07Y7Fmyl1rt2tW4VSrR4hUAJAGQBUAQGnc82SRCUouAKEJQeW4VcZVKqPXqfauZs31NQzaJgFqEqBYhNOK6sHV92boOG1M2BBHGoCD4lFcCcs2NatSSt2qOUecmXCEIyvGLJz9tsen619+s2a+enh1TSEhNuixblKMqr7DoBZCu3BybgoNxbuZfrMpRXalH3frUTqt98ysFBaFo8iSLOprbqvw1v9ax2q1YCbG8TnBSp8623pervT/tVqysOZ5KgGSSIcPyfa57Y+7IubCqc62gw5E61y2nwePbIAUHo+yVlxD8t1chlpY6fHwlzcZnyFRnHmzt81qXrXbUxxQUAJVahFolWn2X1b0OXXUNEtG1p0mDnG+//RYFBQUYOXKkzV6auLg4DBkyBNHR0aiqqsLBgwexZcsWHDhwAJs3b0bbtm0BAEVFRQCAiIgIqzJ8fX0RHh6OwsJCJa24uLje/Oa5OEVFRU4HOaIoIDw80Kl9ryYk5M+5SBdUIiRRgKgSG3U8WaeCPsgfosYfgq+fK6rZKIGB/lfP1IKxfe4lG0RIVTL8wgIh+Dtfl4aur9rXYWPKRlg4/pg5AR0XvgNV6ZUgo/zKjaX4Z8+OFPrnzaUQHIzgENvtEsJCAJVgc5sUHIzyvzyH0JcXQLxcCqGiHFFLanouhIpyCKIAWRAghfwZnDR0LJVKqBkWpRKUPOY0KTQE5a+8ZJE/uO5+5rYKqLmDrVVO5aznLfa1Vefa7Sr7y3M261NX3XIBIPjNZRbzj8TLfwYU9Z0LobQMgixb1Kf2fgBstqsuc50bLMfG8Rt0JbgUbbwfddtqPu+189T3GTJ/fqwOV081bL3X9dGb9AiqrkRYeAA0astrq77rsLHXIBFde5o0yPn4448BAKNGjbK5PSsry+L35ORk9O3bFy+88AIyMjIwf37NSis6nQ4A6h1e5ufnp+QBgKqqqnrz+/n5WeRxhiTJKC2tf26SM1QqESEhGpSWVsFkkgAAJpMEWZIhmyRotRVOly3rdZDKdUC1AMFXclWVHaZSCQgM9EdFhQ4mk/eNwWb7moZsMAB6HSpLKiD4mZwux9b1Zes6rMvwxks1w9HqCgmD718XWJZtlFBerkN1QADkei49m38tL9XZzHvVyfSlupoJ6ZIMQAa0l4GanyADkEJqegEqyvWQzPMg6jmWUk5JKYL+9uqVCpRBkmWYTDLK6tkvQBMI0cbnQ9IE1ruPrTqbidrLNce349hAzR+hAoP8lDbWfc8a6oEwnwulx6xWfWqfvto9Ho62q75yah+/IaIoIBCAZOP8iHV6hMznvfZ71uBnqIH3tTH0Jj2qTDqU+FZCp7a8EOpeh/Zcg84KCdGwh4jIizVZkHP58mV8/vnn6Ny5M/r06WP3fiNGjMCyZcuwb98+Jc3/yl9rDQaDzX10Oh1at26t/G5emc1gMCj7mun1eos8zjIa3RMsmEySUrZ85RtKlht3PNkoQTZKgI8EwcVfGo6p+XIxmWSXf3k1D2xfU5AlCTBKkIwSBFUjrosGrq/a16HVfpdLbM8hqFWOuWxAhsko4cwT4+GraqAX1YXvpykosN65GtKVHnVJsuMcmsuQZevhVHL9+//xVAM30fXsY6vO9c6vaeDYNWo+p/W1scH6XaljQ++hzXk6DrSrwXIaKOtPNe1TSrV1fmA5l8YUFOjRa1YySTAZJRhNEoywrEd912FD1yARkS1NFuRs27YNBoMBDz74oMP7RkZGIi8vT/ndPMSs9pA0M71ej5KSEotAyjzMrbCwENHR0Rb5zUPfuIQ0ETWKKADBYc1udaiGJsqrVGK9w4/qqrvogb3bnGGrzg0tBuBurlpswJ2LFkhBQY4HUEREXqzJgpysrCz4+PhgxIgRDu0nyzLOnDlj0TPTpk0bRERE4PDhw1b5Dx8+DFmWERcXp6TFxcVh06ZNyMvLswpy8vLyEBAQgM6dOztULyIiC8FhUM3N+HN1qLKSPx9wWFbi0aq5gqdvkj19/OauaPIkL+0xJiJyTpMMRj169Ch+/vlnDBw4ENddd53NPBcuXLCZnpmZicLCQtxzzz0W6UlJSSgoKMCePXss0teuXQu1Wo1hw4YpaYmJidBoNMjMzITRaLSoV25uLoYOHcrlo4nItSS5Jti5rG1WPTtERETXAod7crZu3Yo//vgDAHDp0iVUV1djxYoVAICQkBCMGzfOah/zggINDVVbtWoVvvnmG9x9991o37499Ho9Dh48iL179yI6OhpTpkyxyD9x4kTs3r0bM2fORH5+PqKiopCTk4O9e/di8uTJFs/zadWqFaZNm4aFCxciLS0NKSkp0Gq1WLduHVq3bo2pU6c6+jYQEdkWElbvJrmeZ4wQERGRazkc5GRnZ+PQoUMWaW+//TaAmrkzdYMcnU6HTz/9FBERERgwYEC95d5xxx04ceIEtm3bBq1WC0EQ0LFjR0yaNAlPPPEEguvcHISGhmLjxo1YunQpNm/ejPLycnTq1Alz587FmDFjrMpPT09HeHg41q5di4ULF0Kj0aBfv36YPn065+MQkcuops+vd1u1SQdczKt3OxEREbmGw0FOZmamQ/n9/f3x3XffXTVfYmIiEhMTHSq7bdu2WLRokd35k5OTkZyc7NAxiIiIiIioZeEC8URERERE5FUY5BARERERkVdhkENERERERF6lyZ6TQ0TU0pnemgOUllgmesEzcIiIiLwNgxwiInuVltQ894aIiIiaNQY5RESOEgUgOMwyrYHn4xAREVHTYpBDROSo4DCo5mZ4uhZERERUDy48QEREREREXoVBDhEREREReRUGOURERERE5FUY5BARERERkVfhwgNERETUvJSVwDT3WUgCcEElwhQYAnHafE/XiohaEAY5REQtxLL8t1BWXWqVHuwTgue6TvdAjYjcRJKBy1rIAiCJAmCSPF0jImphGOQQETXCC4emQWuwfkBouG84XrttqUuPVVZdilLDZZeWSdSs1H3eVNllALInakJELRyDHCKi2q4MkwFg11AZrUELrf6Sdbr+EiZ+/ZhFWqhPKFJveNhmOfX10lhUrboMACAIIoJ9glFWXQZZ5l+4yXuoplteZ9IrzwJlJZ6pDBG1aAxyiIhquzJMBoBDQ2UEQUCYb7hFwFM3+GkoIHGklybYJxgv9ZyLBYfnuqRn5x9H30SpoeEA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O3bsQFxcHJYvX46IiAiXHKu5+vvf/46AgAAMGjQInTt3RklJCbZs2YInn3wSzz//PJ5++mmL/O+99x60Wi1uvfVWVFVV2XxgvdlPP/2Ehx56CKGhoXjooYfQrl07nD59Gh999BE+//xzZGVl4eabb1by5+TkYMqUKbjpppswffp0GAwGbNiwAWPGjMGHH35oV6Bz+fJlnDp1Cv3790f79u3h7++PU6dOISsrCzt37sSmTZssjvnpp59ixowZiIqKwlNPPQWNRoM9e/bghRdeQGFhISZNmmRRviN1rK6uxoQJE3D06FGMHTsWsbGxyM3NxZIlS3Dy5EmH5ts3hEEOERERkZOu878Om4dv9nQ1MHr7aJf1LN1yyy1ISUmxSJs1axZWr16NJUuWYOLEidiyZYvL/uLuThUVFQgMDHR4vzfffBN33HEHBEFQ0saNG4cRI0bgnXfewdixYxEaGqps+9e//oX27dtDFEU89dRTDQY5H374IfR6PVavXo0uXboo6T179sQzzzyDf//73/jLX/4CADAajZg/fz7atm2LDz/8EEFBQQCAoUOH4v7778eiRYuwbt26q7anc+fO+PDDD63ShwwZgtTUVPzrX//C/PnzlWO++uqruO6667BlyxaEhIQo7X/yySexfPly3H///crjWhytY3Z2Ng4fPoxZs2Zh/PjxAIDU1FQEBwdjw4YNGDVqFPr06XPVNl0NFx4gIiIiogYJgoCJEyfi/vvvx7Fjx7Bz506L7VqtFq+++iruvvtudOvWDf3798dLL72E4uJii3wHDx5EbGwstmzZgo8//hjDhg1Dt27dMHDgQKxevdrmsb/88kuMHTsW8fHx6NmzJx588EHs2LHDKl9aWhruuecenD17Fs899xxuu+029OrVC0BN78Fvv/2mPOvxau68806LAAcANBoN7r77blRXV1s9+zEqKgqiaN9tdVlZGYCaVYJrM//u7++vpOXm5uLcuXNITU1VggcAaN++PYYMGYJvv/0WRUVFdh3XlqioKAA1PT1mv/76Ky5duoTExEQlwAFqPgMjRoxAdXU1tm3b5nQdt2/fDn9/f6tHvpgDntplNwaDHCIiIiKyy+jRowEA+/btU9LKy8sxduxYbNiwAXfeeSdefPFFDB48GJ988glGjx6NCxese5g+/PBDvPvuuxg+fDhmzZqFNm3a4M0338T2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CCNHjvR0lRpl3bp1CAkJaXQ7Ll++jK1bt2L//v347bffoNVqcf311+O2227D5MmTcf3111vtYzAY8N5772Hr1q0oLCxEmzZtMGzYMEyZMgUajcYq/w8//IClS5fi8OHDkCQJ3bp1w3PPPYe+ffvaXc+dO3fiq6++wg8//IDffvsNJpMJOTk5iIqKspm/oKAAK1euxLfffovi4mKEhYWhW7dueOKJJ9CrV69G1dHR9ruKw0HOqlWrkJ+fj/z8fBQUFCAyMhJffvllvfkvXLiAJUuWYP/+/SgrK0N0dDTS0tIwevRom/l37NiBNWvW4Pjx49BoNEhISMCMGTMQGRnZpGUTERERXZUgQgwN83QtIF0uAWTJZeVt374der0eHTt2RFZWVosPcv71r38hMjKy0e34/vvvsXjxYtxxxx145JFHEB4ejl9//RWbNm3Crl278NFHH+Gmm26y2Ocvf/kLdu/ejZSUFPTt2xc///wz1q5dix9++AFr166FKP652PGRI0eQlpaG6667DpMnT4avry82b96Mxx57DKtXr0a/fv3squeHH36I77//Hl26dEHHjh1x8uTJevMWFRVh1KhRkCQJDz/8MDp27IiioiJ89NFHGDduHFavXo2EhASn6+hI+13J4SDnrbfeQlhYGG699VaUlZU1mLe0tBRjx45FUVER0tPTERUVhZycHMyZMwfFxcWYMmWKRf4NGzZg/vz56NWrF2bPng2tVov169cjNzcXWVlZaNeuXZOUTURERGQPMTQMrd9e4+lq4MLUx13as5SVlYW+ffti6NCheOWVV3DixAl07tzZZeW3VJ07d8Znn32GTp06WaTffffdGD9+PJYtW4Zly5Yp6V999RV2796NtLQ0/O1vf1PSIyMj8dprr2H79u1ISUlR0hcsWABRFLFhwwa0b98eADBixAjcf//9eOWVV/DZZ59BEISr1vO1115D27ZtoVarMW/evAaDnK1bt6KkpATvvPMOBg0apKQnJiZixIgRyMrKsghyHKmjo+13JYdDpy+++AIHDx7E2rVr0bZt2wbzrl69GqdPn8Ybb7yB6dOnY/To0Vi1ahUGDhyIlStX4uzZs0perVaLJUuWoGvXrsjMzMSYMWMwefJk/POf/8T58+ctPjDuLpuIiIjoWvXzzz8jPz8fDzzwAJKSkuDr64vs7GybeQ0GA1avXo2U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VSCiBvApWERERERE5FUY5BARERFRi/Lss8/i2LFjnI9D9WKQQ0REREREXoVBDhEREREReRUGOURERERE5FUY5BARERERkVdhkENERERERF6FQQ4REREREXkVBjlERERERORVGOQQEREREZFXYZBDRERERERehUEOERERERF5FQY5RERERETkVRjkEBERERGRV2GQQ0REREREXoVBDhEREREReRUGOURERERE5FUY5BARERERkVdhkENERERERF6FQQ4REREREXkVBjlERERERORVGOQQEREREZFXYZBDRERERERehUEOERERERF5FQY5RERERETkVRjkEBERERGRV2GQQ0REREREXoVBDhEREREReRW1OwvPyMjA8uXL6z+4Wo38/Pyr5n300Ufx0ksvWaXv2LEDa9aswfHjx6HRaJCQkIAZM2YgMjLSKu+FCxewZMkS7N+/H2VlZYiOjkZaWhpGjx7tZOuIiIiIiKg5cmuQM3jwYHTs2NEq/dixY3j//fcxcOBAq22zZ89GeHi4RdqNN95olW/Dhg2YP38+evXqhdmzZ0Or1WL9+vXIzc1FVlYW2rVrp+QtLS3F2LFjUVRUhPT0dERFRSEnJwdz5sxBcXExpkyZ4oLWEhERERFRc+DWIKdLly7o0qWLVfrf//53AMCDDz5otW3QoEGIiopqsFytVoslS5aga9euyMzMhFpd04wBAwYgNTUVy5Ytw4IFC5T8q1evxunTp5GRkYF7770XADB69GhMmjQJK1euREpKCjp06OB0O4mIiIiIqPlo8jk5VVVV+PTTT9GuXTsMGDDAZp7y8nJUV1fXW0ZOTg4qKyuRlpamBDgAEBcXh759+2LXrl0wGAxK+vbt2xEVFaUEOGbjx49HdXU1du3a1chWERERERFRc+HWnhxbdu3ahfLycqSlpUGlUlltT0lJQXl5OURRxC233IInnngCw4YNs8hz5MgRAEB8fLzV/vHx8Th06BBOnDiBLl264Pz58zh37hySkpJs5hUEQSmvMdRq18aLBkGo+UEQXF62bBIhqUVAFCGoPLf2hEol1Hr1vjUw2L6mIZtEQC1CVIsQXHytCBCUV1dch2qIUKlFiCoRKg9ee2aiKNR69Xx93MHb29gS2ydChAoi1CrRoevK1d+FROTdmjzIycrKgiAIGDVqlEV6cHAwUlNT0atXL4SFheHM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7+OGG25wqNysrCxcf/31uHTpErKzs/H888/bva/589YSg5zff/8dy5cvR2RkpFWQ07dvXxw5cgRq9bX5dfT+++97ugpERF7p2vxWoSaRkpJi8fvBgwexcuVKxMbGWm2j5mPw4MH49NNPMXv2bPj6+irpR44cwS+//IKkpCTs2LHDYh9ZljF16lT8+OOPmDdvHh566CGL7Y899hjGjRuHGTNmICsrCzfffLPF9jZt2lh9Jp577jkcOHAAU6ZMwdNPP41///vfDvV8OOv8+fOYPHkyTCYTNm7ciO7duyvbHnnkEezfvx/PPPMMnn76aWzduhX+/v52lavVapGTk4OJEyfit99+wyeffILnnnsOouj5UcMVFRUIDAz0yLFFUYSfn59Hju0pkiTBYDDA39/f4hojIiLX8fy3K9EVtubkmNMuXbqEWbNm4fbbb0d8fDwmT56M8+fPAwA2bdqEoUOHIi4uDkOGDMHnn39us/ydO3dizJgxiI+PR48ePZCamorPPvvMKt++ffswbtw43HHHHYiLi0P//v0xadIk/PrrrwBqhjwtX74cAJCYmIjY2FiLOQW//fYb5s6di/vvv1851siRI7F582arY2VkZCA2NhbHjx/HggUL0L9/f/Ts2RPp6ek4ceIEAGDPnj144IEH0L17dwwcOBAffvihVTnmsff//e9/MXr0aPTo0QP9+vXDq6++ioqKCntPAQBg5MiRuHz5Mr744guL9C1btqBVq1YYOHCg1T579+7Fd999h6FDh1oFOADQoUMHzJs3DzqdzqG5JgkJCXjhhRdQUVGBVatWOdQOZ73//vu4dOkSpk+fbhHgmN1111149NFHcfLkSWRlZdld7rZt21BdXY0RI0bggQceQGFhIb766qur7meeswIAn3zyifJ5qzuPw97Pt/mz8s033yj5J02aBKBmiF9aWhp+/fVXTJgwAfHx8ejduzeee+455XozKyoqwuLFi5GSkoK+ffsiLi4Ow4YNw3vvvQeTyaTky8jIwKOPPgoAmD17tlJ/81yR+ubkVFVVYenSpbj33nvRrVs33HHHHXj++edx8uRJi3y15zB98cUXGDlypHLdvvbaazAajVd9j2u/L/ZeQ2VlZXjjjTcwePBgpX7Tp0/H2bNnLfJt2bIFsbGx+O9//4t33nkHgwYNQlxcHHbu3Amg/jk5//vf/zBhwgT0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q9Uqv//2228AYHXjVtuFCxcA1AQbX375JebNm4clS5agV69eGDBgAO6//360bt3arrpWVFRg+fLl2LVrF86dO2e1vbS01CrN0fb9/vvvVul1h+8ANTesISEhFjen9ggNDcWgQYPwySefIDk5Gd9++y3mzJlTb/7awUtYWFi9+ewNhurbz92T483l2xOElZeX27WMdFVVFT799FPcdtttuHDhgvJZ8/HxwQ033ICsrCw89thjTtfZkc+3WadOnerNa2txB/M5LSkpUdKMRiPee+89/Pvf/8bp06et5orY+pzb6+zZs2jdurUyFLS2mJgYfPvttygoKECXLl3srrc9nx17rqFLly6hpKQE33zzTb2Boq2hodHR0Vc9PlAzxwgAbrrpJqtt5kDGPO/H/Gqr3rb2JyK6ljDIoRZBpVI5lF6b+ebrvffeg4+Pj8085huCsLAwZGVl4X//+x8OHDiA7777Dq+99hqWLVuGFStW2LWM8YwZM7Bv3z6MHj0affv2RWhoKNRqNfbv349169ZBkiSrfeqbL2NP+8xq9wTVJstyvdsaMnLkSOzcuRNz5syBj48PkpKS6s178803Iz8/Hz/++CP69etXbz1+/PFH+Pr62n3DB9T0hp08eRJt27ZVggrzX8R1Ol29+1VVVdm8SW5IUFAQ2rdvj5MnT6KyshIBAQE28506dQoVFRW47bbbrlrm7t27UV5ejv3792P//v0283z//ffo0aOHQ3U1c+TzbVa7t7Guhj5ztQOZRYsWYcOGDRg2bBgmTZqEVq1awcfHB/n5+XjzzTdtfs7tVTdgsmebvfVuiD3XkLms22+/3e65PgDsXoXP3rrWZqvezlzzRETehEEOeb3o6Gh89dVXiIiIsOsBpaIoom/fvsrE/t9++w0jR45ERkaGEuTUdwNRWlqKffv2ISUlRZl4bfbf//63kS1p2PHjx63SiouLUVZW5tTSywkJCbj++utx4MABJCUlNfg8oMGDB2Pr1q3YtGlTvUHO/v37UVRUhHvvvdehZXO3bNmC6upqi1XdwsPDERAQoPRi1GUePmTrWT9XM3jwYKxfvx6ffPKJ1YR9s02bNgEA7r333quWl5WVhTZt2uBvf/ub1TZJkjBz5kxkZ2c7HeQ4+vl2lW3btqFv375YunSpRbqtoZSO3nB37NgR//nPf6DVaq0C1ePHj0MURave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\n",
"text/plain": [
"
"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"bpl.plot_alternation_hist(d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the previous alternation histogram looks correct, \n",
"the corresponding definitions of the excitation periods can be applied to the data using the following command:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# Total photons (after ALEX selection): 2,259,522\n",
"# D photons in D+A excitation periods: 721,537\n",
"# A photons in D+A excitation periods: 1,537,985\n",
"# D+A photons in D excitation period: 1,434,842\n",
"# D+A photons in A excitation period: 824,680\n",
"\n"
]
}
],
"source": [
"loader.alex_apply_period(d)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the previous histogram does not look right, the parameters in the `d.add(...)` cell can be modified and checked by running the histogram plot cell until everything looks fine. Don't forget to apply the \n",
"parameters with `loader.usalex_apply_period(d)` as a last step.\n",
"\n",
"> **NOTE:** After applying the ALEX parameters a new array of \n",
"> timestamps containing only photons inside the excitation periods \n",
"> is created (name `d.ph_times_m`). To save memory, by default, \n",
"> the old timestamps array (`d.ph_times_t`) is deleted. Therefore, \n",
"> in the following, when we talk about all-photon selection we always \n",
"> refer to all photons inside both excitation periods."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Background and burst search"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" - Calculating BG rates ... Channel 0\n",
"[DONE]\n"
]
}
],
"source": [
"d.calc_bg(bg.exp_fit, time_s=30, tail_min_us='auto', F_bg=1.7)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" - Performing burst search (verbose=False) ...[DONE]\n",
" - Calculating burst periods ...[DONE]\n",
" - Counting D and A ph and calculating FRET ... \n",
" - Applying background correction.\n",
" [DONE Counting D/A]\n"
]
}
],
"source": [
"d.burst_search(L=10, m=10, F=6)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we filter the bursts to avoid creating big files:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"ds = d.select_bursts(select_bursts.size, th1=60)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exporting Burst Data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"By burst-data we mean all the scalar burst parameters, e.g. size, duration, background, etc...\n",
"\n",
"We can easily get a table (a pandas DataFrame) with all the burst data as follows:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
size_raw
\n",
"
t_start
\n",
"
t_stop
\n",
"
i_start
\n",
"
i_stop
\n",
"
bg_period
\n",
"
width_ms
\n",
"
bg_ad
\n",
"
bg_dd
\n",
"
bg_aa
\n",
"
bg_da
\n",
"
E
\n",
"
S
\n",
"
nd
\n",
"
na
\n",
"
nt
\n",
"
nda
\n",
"
naa
\n",
"
spot
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
147
\n",
"
1.732456
\n",
"
1.735530
\n",
"
5276
\n",
"
5422
\n",
"
0
\n",
"
3.074012
\n",
"
2.993976
\n",
"
1.795806
\n",
"
1.738086
\n",
"
0.249776
\n",
"
0.324223
\n",
"
0.571004
\n",
"
54.204194
\n",
"
26.006024
\n",
"
140.472131
\n",
"
-0.249776
\n",
"
60.261914
\n",
"
0
\n",
"
\n",
"
\n",
"
1
\n",
"
213
\n",
"
1.792993
\n",
"
1.795878
\n",
"
5961
\n",
"
6173
\n",
"
0
\n",
"
2.884513
\n",
"
2.809410
\n",
"
1.685103
\n",
"
1.630940
\n",
"
0.234378
\n",
"
0.420886
\n",
"
0.648480
\n",
"
77.314897
\n",
"
56.190590
\n",
"
205.874547
\n",
"
0.765622
\n",
"
72.369060
\n",
"
0
\n",
"
\n",
"
\n",
"
2
\n",
"
230
\n",
"
2.023545
\n",
"
2.026337
\n",
"
6757
\n",
"
6986
\n",
"
0
\n",
"
2.791962
\n",
"
2.719270
\n",
"
1.631036
\n",
"
1.578611
\n",
"
0.226858
\n",
"
0.451800
\n",
"
0.467038
\n",
"
57.368964
\n",
"
47.280730
\n",
"
224.071083
\n",
"
-0.226858
\n",
"
119.421389
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
113
\n",
"
3.113880
\n",
"
3.116244
\n",
"
10403
\n",
"
10515
\n",
"
0
\n",
"
2.363913
\n",
"
2.302365
\n",
"
1.380973
\n",
"
1.336586
\n",
"
0.192077
\n",
"
0.166462
\n",
"
0.984595
\n",
"
88.619027
\n",
"
17.697635
\n",
"
107.980076
\n",
"
-0.192077
\n",
"
1.663414
\n",
"
0
\n",
"
\n",
"
\n",
"
4
\n",
"
78
\n",
"
3.129707
\n",
"
3.133044
\n",
"
10548
\n",
"
10625
\n",
"
0
\n",
"
3.337650
\n",
"
3.250750
\n",
"
1.949821
\n",
"
1.887150
\n",
"
0.271197
\n",
"
0.137702
\n",
"
0.998409
\n",
"
61.050179
\n",
"
9.749250
\n",
"
70.912280
\n",
"
-0.271197
\n",
"
0.112850
\n",
"
0
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" size_raw t_start t_stop i_start i_stop bg_period width_ms \\\n",
"0 147 1.732456 1.735530 5276 5422 0 3.074012 \n",
"1 213 1.792993 1.795878 5961 6173 0 2.884513 \n",
"2 230 2.023545 2.026337 6757 6986 0 2.791962 \n",
"3 113 3.113880 3.116244 10403 10515 0 2.363913 \n",
"4 78 3.129707 3.133044 10548 10625 0 3.337650 \n",
"\n",
" bg_ad bg_dd bg_aa bg_da E S nd \\\n",
"0 2.993976 1.795806 1.738086 0.249776 0.324223 0.571004 54.204194 \n",
"1 2.809410 1.685103 1.630940 0.234378 0.420886 0.648480 77.314897 \n",
"2 2.719270 1.631036 1.578611 0.226858 0.451800 0.467038 57.368964 \n",
"3 2.302365 1.380973 1.336586 0.192077 0.166462 0.984595 88.619027 \n",
"4 3.250750 1.949821 1.887150 0.271197 0.137702 0.998409 61.050179 \n",
"\n",
" na nt nda naa spot \n",
"0 26.006024 140.472131 -0.249776 60.261914 0 \n",
"1 56.190590 205.874547 0.765622 72.369060 0 \n",
"2 47.280730 224.071083 -0.226858 119.421389 0 \n",
"3 17.697635 107.980076 -0.192077 1.663414 0 \n",
"4 9.749250 70.912280 -0.271197 0.112850 0 "
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bursts = bext.burst_data(ds, include_bg=True, include_ph_index=True)\n",
"bursts.head(5) # display first 5 bursts"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once we have the DataFrame, saving it to disk in CSV format is trivial:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"bursts.to_csv('%s_burst_data.csv' % filename.replace('.hdf5', ''))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Exporting Bursts Timestamps"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A convenient way to deal with timestamps (and nanotimes if available) \n",
"of photons inside bursts is exporting them as a DataFrame.\n",
"The function `bext.burst_photons` ([documentation](http://fretbursts.readthedocs.io/en/latest/plugins.html#fretbursts.burstlib_ext.burst_photons)) \n",
"will export this \"photon data\"\n",
"with one row per photon. The columns are `timestamp` and, if available,\n",
"`nanotime`."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/paul/anaconda3/envs/Py38/lib/python3.8/site-packages/fretbursts/burstlib_ext.py:436: FutureWarning: arrays to stack must be passed as a \"sequence\" type such as list or tuple. Support for non-sequence iterables such as generators is deprecated as of NumPy 1.16 and will raise an error in the future.\n",
" times_arr = np.hstack(\n",
"/home/paul/anaconda3/envs/Py38/lib/python3.8/site-packages/fretbursts/burstlib_ext.py:438: FutureWarning: arrays to stack must be passed as a \"sequence\" type such as list or tuple. Support for non-sequence iterables such as generators is deprecated as of NumPy 1.16 and will raise an error in the future.\n",
" stream_arr = np.hstack(\n"
]
},
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
\n",
"
timestamp
\n",
"
stream
\n",
"
\n",
"
\n",
"
burst
\n",
"
ph
\n",
"
\n",
"
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
0
\n",
"
138596500
\n",
"
AexAem
\n",
"
\n",
"
\n",
"
1
\n",
"
138622303
\n",
"
DexDem
\n",
"
\n",
"
\n",
"
2
\n",
"
138626950
\n",
"
DexDem
\n",
"
\n",
"
\n",
"
3
\n",
"
138641792
\n",
"
AexAem
\n",
"
\n",
"
\n",
"
4
\n",
"
138643022
\n",
"
DexDem
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" timestamp stream\n",
"burst ph \n",
"0 0 138596500 AexAem\n",
" 1 138622303 DexDem\n",
" 2 138626950 DexDem\n",
" 3 138641792 AexAem\n",
" 4 138643022 DexDem"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"burstph = bext.burst_photons(ds)\n",
"burstph.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This DataFrame has a two-level index (the first two columns): one is \n",
"the burst number and the other is the photon number within each burst.\n",
"The photon number starts at 0 for the first photon of each burst.\n",
"\n",
"As with any DataFrame, saving to disk is trivial:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"burstph.to_csv('photon_data.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To read the data back use:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
\n",
"
timestamp
\n",
"
stream
\n",
"
\n",
"
\n",
"
burst
\n",
"
ph
\n",
"
\n",
"
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
0
\n",
"
138596500
\n",
"
AexAem
\n",
"
\n",
"
\n",
"
1
\n",
"
138622303
\n",
"
DexDem
\n",
"
\n",
"
\n",
"
2
\n",
"
138626950
\n",
"
DexDem
\n",
"
\n",
"
\n",
"
3
\n",
"
138641792
\n",
"
AexAem
\n",
"
\n",
"
\n",
"
4
\n",
"
138643022
\n",
"
DexDem
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" timestamp stream\n",
"burst ph \n",
"0 0 138596500 AexAem\n",
" 1 138622303 DexDem\n",
" 2 138626950 DexDem\n",
" 3 138641792 AexAem\n",
" 4 138643022 DexDem"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"burstph2 = pd.read_csv('photon_data.csv', index_col=(0, 1))\n",
"burstph2.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Verify the data we read is the same:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"timestamp True\n",
"stream True\n",
"dtype: bool"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(burstph2 == burstph).all()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Using the timestamps DataFrame\n",
"\n",
"Operations on the photon-data DataFrame are very simple.\n",
"\n",
"### Transform the timestamps\n",
"\n",
"An example of a transformation is rescaling to get timestamps in seconds:"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
\n",
"
timestamp
\n",
"
stream
\n",
"
times_s
\n",
"
\n",
"
\n",
"
burst
\n",
"
ph
\n",
"
\n",
"
\n",
"
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
0
\n",
"
138596500
\n",
"
AexAem
\n",
"
1.732456
\n",
"
\n",
"
\n",
"
1
\n",
"
138622303
\n",
"
DexDem
\n",
"
1.732779
\n",
"
\n",
"
\n",
"
2
\n",
"
138626950
\n",
"
DexDem
\n",
"
1.732837
\n",
"
\n",
"
\n",
"
3
\n",
"
138641792
\n",
"
AexAem
\n",
"
1.733022
\n",
"
\n",
"
\n",
"
4
\n",
"
138643022
\n",
"
DexDem
\n",
"
1.733038
\n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" timestamp stream times_s\n",
"burst ph \n",
"0 0 138596500 AexAem 1.732456\n",
" 1 138622303 DexDem 1.732779\n",
" 2 138626950 DexDem 1.732837\n",
" 3 138641792 AexAem 1.733022\n",
" 4 138643022 DexDem 1.733038"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"burstph['times_s'] = burstph.timestamp * d.clk_p\n",
"burstph.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Compute burst-wise quantities\n",
"\n",
"We can compute burst-wise quantities in one step without looping \n",
"using standard [pandas group-by/apply](https://pandas.pydata.org/pandas-docs/stable/groupby.html) operations.\n",
"\n",
"To do that, we group rows (photons) by `'burst'` and compute an arbitrary\n",
"function on each burst (for example the mean time):"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"burst\n",
"0 1.734081\n",
"1 1.794125\n",
"2 2.025197\n",
"3 3.115339\n",
"4 3.131453\n",
" ... \n",
"983 597.336390\n",
"984 597.537687\n",
"985 598.285494\n",
"986 598.396130\n",
"987 598.865273\n",
"Name: times_s, Length: 988, dtype: float64"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"burstph.groupby('burst')['times_s'].mean()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Another example of exporting bursts timestamps\n",
"\n",
"> **NOTE**: This section is provided as an example. Exporting timestamps in this way\n",
"> is not recommended. Use the approach in the previous section instead.\n",
"> The example here is an old example reported for educational purposes only."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Exporting timestamps and other photon-data for each bursts is a little trickier\n",
"because the data is less uniform (i.e. each burst has a different number of photons).\n",
"In the following example, we will save a `csv` file with variable-length columns.\n",
"Each burst is represented by to lines: one line for timestamps and one line for the\n",
"photon-stream (excitation/emission period) the timestamps belongs to.\n",
"\n",
"Let's start by creating an array of photon streams containing\n",
"one of the values 0, 1, 2 or 3 for each timestamp.\n",
"These values will correspond to the DexDem, DexAem, AexDem, AemAem\n",
"photon streams respectively."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[array([False, True, True, ..., False, True, False])]"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ds.A_ex"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"#{0: DexDem, 1:DexAem, 2: AexDem, 3: AemAem}"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1, 3, 3, ..., 1, 3, 0], dtype=int8)"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(ds.A_ex[0].view('int8') << 1) + ds.A_em[0].view('int8')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we define an header documenting the file format. We will also include the \n",
"filename of the measurement. \n",
"\n",
"This is just an example including nanotimes:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# BPH2CSV: ./data/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5\n",
"# Lines per burst: 3\n",
"# - timestamps (int64): in 12.5 ns units\n",
"# - nanotimes (int16): in raw TCSPC unit (3.3ps)\n",
"# - stream (uint8): the photon stream according to the mapping {0: DexDem, 1: DexAem, 2: AexDem, 3: AemAem}\n",
"\n"
]
}
],
"source": [
"header = \"\"\"\\\n",
"# BPH2CSV: %s\n",
"# Lines per burst: 3\n",
"# - timestamps (int64): in 12.5 ns units\n",
"# - nanotimes (int16): in raw TCSPC unit (3.3ps)\n",
"# - stream (uint8): the photon stream according to the mapping {0: DexDem, 1: DexAem, 2: AexDem, 3: AemAem}\n",
"\"\"\" % filename\n",
"print(header)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And this is header we are going to use:"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# BPH2CSV: ./data/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5\n",
"# Lines per burst: 2\n",
"# - timestamps (int64): in 12.5 ns units\n",
"# - stream (uint8): the photon stream according to the mapping {0: DexDem, 1: DexAem, 2: AexDem, 3: AemAem}\n",
"\n"
]
}
],
"source": [
"header = \"\"\"\\\n",
"# BPH2CSV: %s\n",
"# Lines per burst: 2\n",
"# - timestamps (int64): in 12.5 ns units\n",
"# - stream (uint8): the photon stream according to the mapping {0: DexDem, 1: DexAem, 2: AexDem, 3: AemAem}\n",
"\"\"\" % filename\n",
"print(header)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now save the data to disk:"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"out_fname = '%s_burst_timestamps.csv' % filename.replace('.hdf5', '')\n",
"dx = ds\n",
"ich = 0\n",
"\n",
"bursts = dx.mburst[ich]\n",
"timestamps = dx.ph_times_m[ich]\n",
"stream = (dx.A_ex[ich].view('int8') << 1) + dx.A_em[ich].view('int8')\n",
"with open(out_fname, 'wt') as f:\n",
" f.write(header)\n",
" for times, period in zip(bl.iter_bursts_ph(timestamps, bursts),\n",
" bl.iter_bursts_ph(stream, bursts)):\n",
" times.tofile(f, sep=',')\n",
" f.write('\\n')\n",
" period.tofile(f, sep=',')\n",
" f.write('\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Read the file back\n",
"\n",
"For consistency check, we can read back the data we just saved.\n",
"As an exercise we will put the results in a pandas DataFrame\n",
"which is more convenient than an array for holding this data."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We start reading the header and computing \n",
"some file-specific constants. "
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"# BPH2CSV: ./data/0023uLRpitc_NTP_20dT_0.5GndCl.hdf5\n",
"# Lines per burst: 2\n",
"# - timestamps (int64): in 12.5 ns units\n",
"# - stream (uint8): the photon stream according to the mapping {0: DexDem, 1: DexAem, 2: AexDem, 3: AemAem}\n",
"\n"
]
}
],
"source": [
"with open(out_fname) as f:\n",
" lines = []\n",
" lines.append(f.readline())\n",
" while lines[-1].startswith('#'):\n",
" lines.append(f.readline())\n",
" header = ''.join(lines[:-1])\n",
"print(header)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(4, 2)"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stream_map = {0: 'DexDem', 1: 'DexAem', 2: 'AexDem', 3: 'AemAem'}\n",
"nrows = int(header.split('\\n')[1].split(':')[1].strip())\n",
"header_len = len(header.split('\\n')) - 1\n",
"header_len, nrows"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As a test, we load the data for the first burst into a dataframe, converting the numerical column \"streams\"\n",
"into photon-stream names (strings). The new column is of type categorical, so it will take very little space:"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
timestamp
\n",
"
stream
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
138596500
\n",
"
AemAem
\n",
"
\n",
"
\n",
"
1
\n",
"
138622303
\n",
"
DexDem
\n",
"
\n",
"
\n",
"
2
\n",
"
138626950
\n",
"
DexDem
\n",
"
\n",
"
\n",
"
3
\n",
"
138641792
\n",
"
AemAem
\n",
"
\n",
"
\n",
"
4
\n",
"
138643022
\n",
"
DexDem
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
142
\n",
"
138788833
\n",
"
AemAem
\n",
"
\n",
"
\n",
"
143
\n",
"
138790337
\n",
"
DexDem
\n",
"
\n",
"
\n",
"
144
\n",
"
138790703
\n",
"
DexAem
\n",
"
\n",
"
\n",
"
145
\n",
"
138790873
\n",
"
DexAem
\n",
"
\n",
"
\n",
"
146
\n",
"
138842421
\n",
"
DexDem
\n",
"
\n",
" \n",
"
\n",
"
147 rows × 2 columns
\n",
"
"
],
"text/plain": [
" timestamp stream\n",
"0 138596500 AemAem\n",
"1 138622303 DexDem\n",
"2 138626950 DexDem\n",
"3 138641792 AemAem\n",
"4 138643022 DexDem\n",
".. ... ...\n",
"142 138788833 AemAem\n",
"143 138790337 DexDem\n",
"144 138790703 DexAem\n",
"145 138790873 DexAem\n",
"146 138842421 DexDem\n",
"\n",
"[147 rows x 2 columns]"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"burstph = (pd.read_csv(out_fname, skiprows=header_len, nrows=nrows, header=None).T\n",
" .rename(columns={0: 'timestamp', 1: 'stream'}))\n",
"StreamCategorical = pd.api.types.CategoricalDtype(categories=['DexDem', 'DexAem', 'AexDem', 'AemAem'], ordered=True)\n",
"burstph.stream = (burstph.stream\n",
" .apply(lambda x: stream_map[pd.to_numeric(x)])\n",
" .astype(StreamCategorical))\n",
"burstph"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For reading the whole file I use a different approach. First, I load the entire file \n",
"in two lists of lists (one for timestamps and one for the stream). Next, I create\n",
"a single DataFrame with a third column indicating the burst index."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
"
\n",
"
\n",
"
timestamp
\n",
"
stream
\n",
"
iburst
\n",
"
\n",
" \n",
" \n",
"
\n",
"
0
\n",
"
138596500
\n",
"
AemAem
\n",
"
0
\n",
"
\n",
"
\n",
"
1
\n",
"
138622303
\n",
"
DexDem
\n",
"
0
\n",
"
\n",
"
\n",
"
2
\n",
"
138626950
\n",
"
DexDem
\n",
"
0
\n",
"
\n",
"
\n",
"
3
\n",
"
138641792
\n",
"
AemAem
\n",
"
0
\n",
"
\n",
"
\n",
"
4
\n",
"
138643022
\n",
"
DexDem
\n",
"
0
\n",
"
\n",
"
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
...
\n",
"
\n",
"
\n",
"
232327
\n",
"
47909435404
\n",
"
DexAem
\n",
"
987
\n",
"
\n",
"
\n",
"
232328
\n",
"
47909438825
\n",
"
DexAem
\n",
"
987
\n",
"
\n",
"
\n",
"
232329
\n",
"
47909451409
\n",
"
DexDem
\n",
"
987
\n",
"
\n",
"
\n",
"
232330
\n",
"
47909458878
\n",
"
DexAem
\n",
"
987
\n",
"
\n",
"
\n",
"
232331
\n",
"
47909462189
\n",
"
DexDem
\n",
"
987
\n",
"
\n",
" \n",
"
\n",
"
232332 rows × 3 columns
\n",
"
"
],
"text/plain": [
" timestamp stream iburst\n",
"0 138596500 AemAem 0\n",
"1 138622303 DexDem 0\n",
"2 138626950 DexDem 0\n",
"3 138641792 AemAem 0\n",
"4 138643022 DexDem 0\n",
"... ... ... ...\n",
"232327 47909435404 DexAem 987\n",
"232328 47909438825 DexAem 987\n",
"232329 47909451409 DexDem 987\n",
"232330 47909458878 DexAem 987\n",
"232331 47909462189 DexDem 987\n",
"\n",
"[232332 rows x 3 columns]"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import csv\n",
"from builtins import int # python 2 workaround, can be removed on python 3\n",
"\n",
"# Read data in two list of lists\n",
"t_list, s_list = [], []\n",
"with open(out_fname) as f:\n",
" for i in range(header_len):\n",
" f.readline()\n",
" csvreader = csv.reader(f) \n",
" for row in csvreader:\n",
" t_list.append([int(v) for v in row])\n",
" s_list.append([int(v) for v in next(csvreader)])\n",
"\n",
"# Turn the inner list into pandas.DataFrame\n",
"d_list = []\n",
"for ib, (t, s) in enumerate(zip(t_list, s_list)):\n",
" d_list.append(\n",
" pd.DataFrame({'timestamp': t, 'stream': s}, columns=['timestamp', 'stream'])\n",
" .assign(iburst=ib)\n",
" )\n",
"\n",
"# Concatenate dataframes\n",
"burstph = pd.concat(d_list, ignore_index=True)\n",
"\n",
"# Convert stream column into categorical\n",
"StreamCategorical = pd.api.types.CategoricalDtype(categories=['DexDem', 'DexAem', 'AexDem', 'AemAem'], ordered=True)\n",
"burstph.stream = (burstph.stream\n",
" .apply(lambda x: stream_map[pd.to_numeric(x)])\n",
" .astype(StreamCategorical))\n",
"burstph"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"timestamp int64\n",
"stream category\n",
"iburst int64\n",
"dtype: object"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"burstph.dtypes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This was just an example. There are certainly more efficient ways \n",
"to read the file into a DataFrame. Please feel free to contribute\n",
"new methods to illustrate a different (more efficient or simpler)\n",
"approach."
]
}
],
"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.8.13"
},
"nav_menu": {},
"toc": {
"nav_menu": {
"height": "174px",
"width": "252px"
},
"number_sections": false,
"sideBar": true,
"skip_h1_title": false,
"toc_cell": false,
"toc_position": {
"height": "592px",
"left": "0px",
"right": "958px",
"top": "111px",
"width": "257px"
},
"toc_section_display": "block",
"toc_window_display": true
}
},
"nbformat": 4,
"nbformat_minor": 1
}