{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook shows a general example of mass balance calculation, we currently support two algorithms:\n", "\n", "1. [Non-negative algorithm](https://epubs.siam.org/doi/pdf/10.1137/1.9781611971217.bm), it solves KKT (Karush-Kuhn-Tucker) conditions for the non-negative least squares problem\n", " \n", "2. Matrix decomposition, following [Li et al. (2020)](https://www.sciencedirect.com/science/article/pii/S0009281920300301?casa_token=sT59EIzD3QkAAAAA:bQSW0-dssOb6YRtOMb-69ctkXC0BzW5_zlalxk4EV2GFwhm4apnk73tsq4TKVc4vipPyIImq8Twg) and [Ghiorso 1983](https://www.sciencedirect.com/science/article/pii/0098300483900080). The compositional matrix will be broken down by singular value decomposition, the coefficients will then calculated." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# import python modules\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "from massbalance.mb_tools import MassBalance " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1. Define elements for calculation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We first need to define element list for mass balance calculation, special attention goes to `FeO` term, which we use `FeO`, not ``FeOt`` nor ``FeOtot``, this is consistent with the input excel files. Feel free to change the order of the elements" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "cmpnts = ['SiO2','Al2O3', 'TiO2', 'MgO', 'FeO', 'MnO', 'CaO', 'Na2O', 'K2O', 'P2O5', 'Cr2O3'] # change your desired elements for mass balance calculation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "if you also want to integrate standard deviation on elements, this can be done manually or by the following line" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['SiO2_std',\n", " 'Al2O3_std',\n", " 'TiO2_std',\n", " 'MgO_std',\n", " 'FeO_std',\n", " 'MnO_std',\n", " 'CaO_std',\n", " 'Na2O_std',\n", " 'K2O_std',\n", " 'P2O5_std',\n", " 'Cr2O3_std']" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cmpnts_std =[x + '_std' for x in cmpnts] # save columns for std\n", "cmpnts_std" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. Load data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The easist way is to copy paste data in the input excel file, please also check README file for details of data prepration" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "nat_comp = pd.ExcelFile(\"input_comp.xlsx\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We load the whole excel spreadsheet to a pandas ExcelFile, to access data in your spreadsheet, you can do so by looping through ExcelFile to a dictionary:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "nat_dict = {} # create dictionary to collect compositions of different phases\n", "nat_phases = [] # create list to save all phases in the calculation. Note bulk will be the bulk compsition, run_index will be your sample number, or rock id . etc\n", "for sheet_name in nat_comp.sheet_names:\n", " nat_phases.append(sheet_name)\n", " nat_dict[sheet_name] = nat_comp.parse(sheet_name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``nat_phases`` stores the sheet names, ``nat_dict`` stores the data of each sheet. " ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['gl', 'ol', 'sp', 'py', 'pureFe', 'pureNa', 'bulk', 'run_index']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nat_phases" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use the sheet name to access data, let's what we have in the ``gl`` phase\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Run_noSiO2Al2O3P2O5CaOFeONa2OMgOTiO2K2O...Al2O3_stdP2O5_stdCaO_stdFeO_stdNa2O_stdMgO_stdTiO2_stdK2O_stdMnO_stdCr2O3_std
002As146.6610.160.1711.6413.061.9513.152.430.49...0.170.100.220.340.100.260.200.040.040.04
101As146.9610.340.2011.8113.211.8412.162.530.44...0.110.070.200.210.100.120.140.050.030.08
204As147.2010.800.2312.1312.771.8711.042.650.48...0.110.050.210.450.140.090.160.050.050.03
303As148.3811.360.1812.6313.031.4210.352.540.43...0.160.060.120.270.070.190.270.050.050.05
405As147.1811.630.2312.8412.572.049.422.600.51...0.120.050.250.200.120.180.230.050.040.05
\n", "

5 rows × 25 columns

\n", "
" ], "text/plain": [ " Run_no SiO2 Al2O3 P2O5 CaO FeO Na2O MgO TiO2 K2O ... \\\n", "0 02As1 46.66 10.16 0.17 11.64 13.06 1.95 13.15 2.43 0.49 ... \n", "1 01As1 46.96 10.34 0.20 11.81 13.21 1.84 12.16 2.53 0.44 ... \n", "2 04As1 47.20 10.80 0.23 12.13 12.77 1.87 11.04 2.65 0.48 ... \n", "3 03As1 48.38 11.36 0.18 12.63 13.03 1.42 10.35 2.54 0.43 ... \n", "4 05As1 47.18 11.63 0.23 12.84 12.57 2.04 9.42 2.60 0.51 ... \n", "\n", " Al2O3_std P2O5_std CaO_std FeO_std Na2O_std MgO_std TiO2_std \\\n", "0 0.17 0.10 0.22 0.34 0.10 0.26 0.20 \n", "1 0.11 0.07 0.20 0.21 0.10 0.12 0.14 \n", "2 0.11 0.05 0.21 0.45 0.14 0.09 0.16 \n", "3 0.16 0.06 0.12 0.27 0.07 0.19 0.27 \n", "4 0.12 0.05 0.25 0.20 0.12 0.18 0.23 \n", "\n", " K2O_std MnO_std Cr2O3_std \n", "0 0.04 0.04 0.04 \n", "1 0.05 0.03 0.08 \n", "2 0.05 0.05 0.03 \n", "3 0.05 0.05 0.05 \n", "4 0.05 0.04 0.05 \n", "\n", "[5 rows x 25 columns]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nat_dict['gl'].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "we use `run_index` sheet to store all runs we wish to perform mass balance with, we can check by doing:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Run_noT_CfO2
002As11320QFM
101As11302QFM
204As11280QFM
303As11260QFM
405As11240QFM
506As11200QFM
615As11180QFM
717As11170QFM
814As11160QFM
\n", "
" ], "text/plain": [ " Run_no T_C fO2\n", "0 02As1 1320 QFM\n", "1 01As1 1302 QFM\n", "2 04As1 1280 QFM\n", "3 03As1 1260 QFM\n", "4 05As1 1240 QFM\n", "5 06As1 1200 QFM\n", "6 15As1 1180 QFM\n", "7 17As1 1170 QFM\n", "8 14As1 1160 QFM" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nat_dict['run_index']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3. Mass balance calculation with MCMC progagting errors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``MassBalance`` class does the core calculation.\n", "To start the calculation, we need to define the ``MassBalance`` class by passing all necessary infos for calculations:\n", "1. `input_comp` -- load the ExcelFile variable\n", "2. `comp_col` -- load element list\n", "3. `comp_std_col` -- load element std list (if avaiable), default is ``None``\n", "4. `match_column` -- this is the column name that saves your expts run no., sample no., or rock id. in each spreadsheet\n", "5. `bulk_sheet` -- sheet name of which saves bulk composition(s)\n", "6. `index_sheet` -- sheet name stores entire infos about expts run numbers ± condition, sample numbers or rock id.\n", "7. `normalize` -- normalize your data to 100 during calculation, default is ``True``" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "mb_cal = MassBalance(\n", " input_comp=nat_comp,\n", " comp_col=cmpnts,\n", " comp_std_col=cmpnts_std,\n", " match_column=\"Run_no\",\n", " bulk_sheet=\"bulk\",\n", " index_sheet=\"run_index\",\n", " normalize=True,\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "``mb_cal`` is a variable we create for mass balance calculation\n", "The calculation is done by calling the compute method in the `MassBalance` class as `mb_cal.compute()`\n", "Four parameters can be tuned during computing:\n", "1. `mc` -- define the number of MC calculations, the default is None, which will be a one time calculation\n", "2. `exportFiles` -- we can export the results to excel file `output.xlsx` and `output_mean_median_std.xlsx`. If `mc` is given, `output_mean_median_std.xlsx`stores statistical infos for mc results\n", "3. `batch_bulk`: define if you have different bulk for each group of phases, this is useful for layers in layered intrusions or expts with variable starting compositions for different runs. If you only have one bulk composition, can turn it to `False`\n", "4. `method`: use `nnl` for non-negative method, `svd` for matrix decomposition method" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Below we give examples to perform 100 times MC calculation with non-negative method, export files, and we have pre-defined a batch bulk composition in the input file. More examples are given in the python scipt along with this code" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "res_dict = mb_cal.compute(mc=100, exportFiles=True, batch_bulk=True, method='nnl')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The result is saved in a python dictionary, with each key responses to the expts run no., sample no, or rock id you defined in the index sheet\n", "Let's take a look the results of first experimental run `02As1`" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
glolsppypureFepureNar2residues
00.9803090.0252990.00.00.00.0006650.3182160.101261
10.9596950.0310320.00.00.00.0011121.1744061.379230
20.9792350.0193750.00.00.00.0024121.0232951.047133
30.9818380.0117460.00.00.00.0015030.6299610.396851
40.9686290.0350220.00.00.00.0004570.7074380.500469
...........................
950.9816870.0221480.00.00.00.0000001.0306321.062203
960.9801760.0157650.00.00.00.0000000.6611830.437163
970.9809720.0258540.00.00.00.0010350.9506290.903696
980.9742490.0218210.00.00.00.0007741.9530853.814540
990.9937930.0039560.00.00.00.0000000.7337810.538435
\n", "

100 rows × 8 columns

\n", "
" ], "text/plain": [ " gl ol sp py pureFe pureNa r2 residues\n", "0 0.980309 0.025299 0.0 0.0 0.0 0.000665 0.318216 0.101261\n", "1 0.959695 0.031032 0.0 0.0 0.0 0.001112 1.174406 1.379230\n", "2 0.979235 0.019375 0.0 0.0 0.0 0.002412 1.023295 1.047133\n", "3 0.981838 0.011746 0.0 0.0 0.0 0.001503 0.629961 0.396851\n", "4 0.968629 0.035022 0.0 0.0 0.0 0.000457 0.707438 0.500469\n", ".. ... ... ... ... ... ... ... ...\n", "95 0.981687 0.022148 0.0 0.0 0.0 0.000000 1.030632 1.062203\n", "96 0.980176 0.015765 0.0 0.0 0.0 0.000000 0.661183 0.437163\n", "97 0.980972 0.025854 0.0 0.0 0.0 0.001035 0.950629 0.903696\n", "98 0.974249 0.021821 0.0 0.0 0.0 0.000774 1.953085 3.814540\n", "99 0.993793 0.003956 0.0 0.0 0.0 0.000000 0.733781 0.538435\n", "\n", "[100 rows x 8 columns]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res_02As1 = res_dict['02As1']\n", "res_02As1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is the MC results (100 times), to calculate statistical infos, you can simply call the built-in pandas functions as:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
glolsppypureFepureNar2residues
count100.000000100.000000100.0100.0100.000000100.000000100.000000100.000000
mean0.9813660.0205900.00.00.0000100.0005510.8764000.870697
std0.0098310.0078730.00.00.0000920.0006660.3219580.630622
min0.9571790.0003370.00.00.0000000.0000000.2754810.075890
25%0.9760140.0153490.00.00.0000000.0000000.6636420.440423
50%0.9813650.0209790.00.00.0000000.0003440.8121410.660398
75%0.9857750.0254330.00.00.0000000.0009141.0630281.130062
max1.0127580.0425510.00.00.0009100.0028961.9530853.814540
\n", "
" ], "text/plain": [ " gl ol sp py pureFe pureNa \\\n", "count 100.000000 100.000000 100.0 100.0 100.000000 100.000000 \n", "mean 0.981366 0.020590 0.0 0.0 0.000010 0.000551 \n", "std 0.009831 0.007873 0.0 0.0 0.000092 0.000666 \n", "min 0.957179 0.000337 0.0 0.0 0.000000 0.000000 \n", "25% 0.976014 0.015349 0.0 0.0 0.000000 0.000000 \n", "50% 0.981365 0.020979 0.0 0.0 0.000000 0.000344 \n", "75% 0.985775 0.025433 0.0 0.0 0.000000 0.000914 \n", "max 1.012758 0.042551 0.0 0.0 0.000910 0.002896 \n", "\n", " r2 residues \n", "count 100.000000 100.000000 \n", "mean 0.876400 0.870697 \n", "std 0.321958 0.630622 \n", "min 0.275481 0.075890 \n", "25% 0.663642 0.440423 \n", "50% 0.812141 0.660398 \n", "75% 1.063028 1.130062 \n", "max 1.953085 3.814540 " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res_02As1.describe()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or only interested parameters" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
glolsppypureFepureNar2residues
mean0.9813660.0205900.00.00.0000100.0005510.8764000.870697
median0.9813650.0209790.00.00.0000000.0003440.8121410.660398
std0.0098310.0078730.00.00.0000920.0006660.3219580.630622
\n", "
" ], "text/plain": [ " gl ol sp py pureFe pureNa r2 residues\n", "mean 0.981366 0.020590 0.0 0.0 0.000010 0.000551 0.876400 0.870697\n", "median 0.981365 0.020979 0.0 0.0 0.000000 0.000344 0.812141 0.660398\n", "std 0.009831 0.007873 0.0 0.0 0.000092 0.000666 0.321958 0.630622" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res_02As1.agg(['mean', 'median', 'std'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To plot the result, you can simply do:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "fig, axes = plt.subplots(1,2, constrained_layout=True)\n", "axes[0].hist(res_02As1['gl'], density=True)\n", "axes[1].hist(res_02As1['ol'], density=True)\n", "axes[0].set_xlabel('gl')\n", "axes[1].set_xlabel('ol')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We pre-defined pure FeO and pure Na2O phases as the evaluation of Fe loss and Na loss, if you don't want to check this, simply delete these sheets\n", "Below we give an example to calculate Fe loss (%) and Na loss (%) in the first experimental run `02As1`\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "12.42" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nat_bulk = nat_dict['bulk'].set_index('Run_no')\n", "nat_bulk.loc['02As1', 'FeO']" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.96" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "nat_bulk.loc['02As1', 'Na2O']" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "mean 0.008275\n", "median 0.000000\n", "std 0.073758\n", "Name: Fe_loss, dtype: float64" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res_02As1['Fe_loss'] = res_02As1['pureFe'] / nat_bulk.loc['02As1', 'FeO'] * 100 * 100\n", "res_02As1['Fe_loss'].agg(['mean', 'median', 'std'])" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "mean 2.813345\n", "median 1.756814\n", "std 3.398196\n", "Name: Na2O_loss, dtype: float64" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res_02As1['Na2O_loss'] = res_02As1['pureNa'] / nat_bulk.loc['02As1', 'Na2O'] * 100 * 100\n", "res_02As1['Na2O_loss'].agg(['mean', 'median', 'std'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Fin ~ happy coding!" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.9.6 ('base')", "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.6" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "dbfc26f88d4be79d14d7fd08a335d9cb9196b9d1da0cd3f4e161d45a5650b80a" } } }, "nbformat": 4, "nbformat_minor": 2 }