compb-dla-data-analysis/notebooks/bc1.ipynb
2023-03-20 15:02:59 +00:00

313 lines
8.9 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"\"\"\"\n",
"Created on Mon Sep 16 09:47:15 2019\n",
"@author: daniel\n",
"\"\"\"\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"\n",
"def fractal_dimension(array, max_box_size=None, min_box_size=1, n_samples=20, n_offsets=0, plot=False):\n",
" \"\"\"Calculates the fractal dimension of a 3D numpy array.\n",
"\n",
" Args:\n",
" array (np.ndarray): The array to calculate the fractal dimension of.\n",
" max_box_size (int): The largest box size, given as the power of 2 so that\n",
" 2**max_box_size gives the sidelength of the largest box.\n",
" min_box_size (int): The smallest box size, given as the power of 2 so that\n",
" 2**min_box_size gives the sidelength of the smallest box.\n",
" Default value 1.\n",
" n_samples (int): number of scales to measure over.\n",
" n_offsets (int): number of offsets to search over to find the smallest set N(s) to\n",
" cover all voxels>0.\n",
" plot (bool): set to true to see the analytical plot of a calculation.\n",
"\n",
"\n",
" \"\"\"\n",
" # determine the scales to measure on\n",
" if max_box_size == None:\n",
" # default max size is the largest power of 2 that fits in the smallest dimension of the array:\n",
" max_box_size = int(np.floor(np.log2(np.min(array.shape))))\n",
" scales = np.floor(np.logspace(max_box_size, min_box_size, num=n_samples, base=2))\n",
" scales = np.unique(scales) # remove duplicates that could occur as a result of the floor\n",
"\n",
" # get the locations of all non-zero pixels\n",
" locs = np.where(array > 0)\n",
" voxels = np.array([(x, y, z) for x, y, z in zip(*locs)])\n",
"\n",
" # count the minimum amount of boxes touched\n",
" Ns = []\n",
" # loop over all scales\n",
" for scale in scales:\n",
" touched = []\n",
" if n_offsets == 0:\n",
" offsets = [0]\n",
" else:\n",
" offsets = np.linspace(0, scale, n_offsets)\n",
" # search over all offsets\n",
" for offset in offsets:\n",
" bin_edges = [np.arange(0, i, scale) for i in array.shape]\n",
" bin_edges = [np.hstack([0 - offset, x + offset]) for x in bin_edges]\n",
" H1, e = np.histogramdd(voxels, bins=bin_edges)\n",
" touched.append(np.sum(H1 > 0))\n",
" Ns.append(touched)\n",
" Ns = np.array(Ns)\n",
"\n",
" # From all sets N found, keep the smallest one at each scale\n",
" Ns = Ns.min(axis=1)\n",
"\n",
" # Only keep scales at which Ns changed\n",
" scales = np.array([np.min(scales[Ns == x]) for x in np.unique(Ns)])\n",
"\n",
" Ns = np.unique(Ns)\n",
" Ns = Ns[Ns > 0]\n",
" scales = scales[:len(Ns)]\n",
" # perform fit\n",
" coeffs = np.polyfit(np.log(1 / scales), np.log(Ns), 1)\n",
"\n",
" # make plot\n",
" if plot:\n",
" fig, ax = plt.subplots(figsize=(8, 6))\n",
" ax.scatter(np.log(1 / scales), np.log(np.unique(Ns)), c=\"teal\", label=\"Measured ratios\")\n",
" ax.set_ylabel(\"$\\log N(\\epsilon)$\")\n",
" ax.set_xlabel(\"$\\log 1/ \\epsilon$\")\n",
" fitted_y_vals = np.polyval(coeffs, np.log(1 / scales))\n",
" ax.plot(np.log(1 / scales), fitted_y_vals, \"k--\", label=f\"Fit: {np.round(coeffs[0], 3)}X+{coeffs[1]}\")\n",
" ax.legend();\n",
" return (coeffs[0])\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"from lib.lib import read_xy_alt, read_load\n",
"\n",
"full_data = read_load(\"/Users/joshuacoles/Developer/checkouts/jc3091/CompB DLA/data-analysis/data/rust-3d\", read_xy_alt)\n",
"df = full_data[full_data.run == '1']"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"max_actual_radius = max(df.x.abs().max(), df.y.abs().max(), df.z.abs().max())\n",
"max_radius = int(np.exp2(np.floor(np.log2(max_actual_radius)) + 1))\n",
"data = np.zeros((max_radius * 2, max_radius * 2, max_radius * 2))\n",
"data[df.x + max_radius, df.y + max_radius, df.z + max_radius] = 1"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": "(128, 128, 128)"
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.shape"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": "5000.0"
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data.sum()"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": "(5000, 8)"
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.shape"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"dfs = []\n",
"for _, df in full_data.groupby('run'):\n",
" max_actual_radius = max(df.x.abs().max(), df.y.abs().max(), df.z.abs().max())\n",
" max_radius = int(np.exp2(np.floor(np.log2(max_actual_radius)) + 1))\n",
" data = np.zeros((max_radius * 2, max_radius * 2, max_radius * 2))\n",
" data[df.x + max_radius, df.y + max_radius, df.z + max_radius] = 1\n",
" dfs.append(fractal_dimension(data))"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": "0.1543448984741014"
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.mean(np.array(dfs))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.scatter(run1.x, run1.y, run1.z)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from mpl_toolkits.mplot3d import Axes3D\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib as mpl\n",
"from mpl_toolkits.mplot3d import Axes3D\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fig = plt.figure(figsize=(10, 10))\n",
"ax = fig.add_subplot(projection='3d')\n",
"ax.scatter(run1.x, run1.y,run1.z, c=run1.N)\n",
"fig"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run1"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"ename": "ModuleNotFoundError",
"evalue": "No module named 'mpld3'",
"output_type": "error",
"traceback": [
"\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
"\u001B[0;31mModuleNotFoundError\u001B[0m Traceback (most recent call last)",
"Cell \u001B[0;32mIn[24], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[38;5;28;01mimport\u001B[39;00m \u001B[38;5;21;01mmatplotlib\u001B[39;00m\u001B[38;5;21;01m.\u001B[39;00m\u001B[38;5;21;01mpyplot\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m \u001B[38;5;21;01mplt\u001B[39;00m\u001B[38;5;241m,\u001B[39m \u001B[38;5;21;01mmpld3\u001B[39;00m\n",
"\u001B[0;31mModuleNotFoundError\u001B[0m: No module named 'mpld3'"
]
}
],
"source": [
"import matplotlib.pyplot as plt, mpld3"
]
},
{
"cell_type": "code",
"execution_count": null,
"outputs": [],
"source": [],
"metadata": {
"collapsed": false
}
}
],
"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.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 1
}