313 lines
8.9 KiB
Plaintext
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
|
|
}
|