diff --git a/tradebooks/spatial_resolution_&_swath_vs_focal_length_trade.ipynb b/tradebooks/spatial_resolution_&_swath_vs_focal_length_trade.ipynb index 8012d7b..cf92ec6 100644 --- a/tradebooks/spatial_resolution_&_swath_vs_focal_length_trade.ipynb +++ b/tradebooks/spatial_resolution_&_swath_vs_focal_length_trade.ipynb @@ -10,9 +10,21 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 40, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "ImportError", + "evalue": "cannot import name 'orient_and_broadcast' from 'architect.libs.utillib' (C:\\Users\\Optics\\Documents\\GitHub\\architect\\architect\\libs\\utillib.py)", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mImportError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\tradebooks\\spatial_resolution_&_swath_vs_focal_length_trade.ipynb Cell 2\u001b[0m line \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mIPython\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mdisplay\u001b[39;00m \u001b[39mimport\u001b[39;00m display\n\u001b[0;32m 11\u001b[0m \u001b[39m# project\u001b[39;00m\n\u001b[1;32m---> 12\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39marchitect\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mlibs\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39mutillib\u001b[39;00m \u001b[39mimport\u001b[39;00m orient_and_broadcast\n\u001b[0;32m 13\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39marchitect\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39msystems\u001b[39;00m\u001b[39m.\u001b[39;00m\u001b[39moptical\u001b[39;00m \u001b[39mimport\u001b[39;00m foreoptics, masks, sensors, spectrometers\n", + "\u001b[1;31mImportError\u001b[0m: cannot import name 'orient_and_broadcast' from 'architect.libs.utillib' (C:\\Users\\Optics\\Documents\\GitHub\\architect\\architect\\libs\\utillib.py)" + ] + } + ], "source": [ "# stdlib\n", "from pathlib import Path\n", @@ -25,7 +37,7 @@ "from IPython.display import display\n", "\n", "# project\n", - "from architect.libs import utillib\n", + "from architect.libs.utillib import orient_and_broadcast\n", "from architect.systems.optical import foreoptics, masks, sensors, spectrometers" ] }, @@ -39,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -56,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ @@ -74,9 +86,7 @@ "\n", "# region vectorization\n", "parameter_space_shape = (focal_length.size, slit_size.size)\n", - "focal_length = utillib.orient_and_broadcast(\n", - " a=focal_length, dim=0, shape=parameter_space_shape\n", - ")\n", + "focal_length = orient_and_broadcast(a=focal_length, dim=0, shape=parameter_space_shape)\n", "# endregion" ] }, @@ -89,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -115,31 +125,26 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 38, "metadata": {}, "outputs": [ { - "ename": "UnitConversionError", - "evalue": "Can only apply 'maximum' function to quantities with compatible dimensions", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mUnitConversionError\u001b[0m Traceback (most recent call last)", - "File \u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\.venv\\lib\\site-packages\\astropy\\units\\quantity_helper\\helpers.py:68\u001b[0m, in \u001b[0;36mget_converters_and_unit\u001b[1;34m(f, unit1, unit2)\u001b[0m\n\u001b[0;32m 67\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m---> 68\u001b[0m converters[changeable] \u001b[39m=\u001b[39m get_converter(unit2, unit1)\n\u001b[0;32m 69\u001b[0m \u001b[39mexcept\u001b[39;00m UnitsError:\n", - "File \u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\.venv\\lib\\site-packages\\astropy\\units\\quantity_helper\\helpers.py:32\u001b[0m, in \u001b[0;36mget_converter\u001b[1;34m(from_unit, to_unit)\u001b[0m\n\u001b[0;32m 30\u001b[0m \u001b[39m\"\"\"Like Unit._get_converter, except returns None if no scaling is needed,\u001b[39;00m\n\u001b[0;32m 31\u001b[0m \u001b[39mi.e., if the inferred scale is unity.\"\"\"\u001b[39;00m\n\u001b[1;32m---> 32\u001b[0m converter \u001b[39m=\u001b[39m from_unit\u001b[39m.\u001b[39;49m_get_converter(to_unit)\n\u001b[0;32m 33\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mif\u001b[39;00m converter \u001b[39mis\u001b[39;00m unit_scale_converter \u001b[39melse\u001b[39;00m converter\n", - "File \u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\.venv\\lib\\site-packages\\astropy\\units\\core.py:1061\u001b[0m, in \u001b[0;36mUnitBase._get_converter\u001b[1;34m(self, other, equivalencies)\u001b[0m\n\u001b[0;32m 1059\u001b[0m \u001b[39mpass\u001b[39;00m\n\u001b[1;32m-> 1061\u001b[0m \u001b[39mraise\u001b[39;00m exc\n", - "File \u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\.venv\\lib\\site-packages\\astropy\\units\\core.py:1046\u001b[0m, in \u001b[0;36mUnitBase._get_converter\u001b[1;34m(self, other, equivalencies)\u001b[0m\n\u001b[0;32m 1045\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m-> 1046\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_apply_equivalencies(\n\u001b[0;32m 1047\u001b[0m \u001b[39mself\u001b[39;49m, other, \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_normalize_equivalencies(equivalencies))\n\u001b[0;32m 1048\u001b[0m \u001b[39mexcept\u001b[39;00m UnitsError \u001b[39mas\u001b[39;00m exc:\n\u001b[0;32m 1049\u001b[0m \u001b[39m# Last hope: maybe other knows how to do it?\u001b[39;00m\n\u001b[0;32m 1050\u001b[0m \u001b[39m# We assume the equivalencies have the unit itself as first item.\u001b[39;00m\n\u001b[0;32m 1051\u001b[0m \u001b[39m# TODO: maybe better for other to have a `_back_converter` method?\u001b[39;00m\n", - "File \u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\.venv\\lib\\site-packages\\astropy\\units\\core.py:1022\u001b[0m, in \u001b[0;36mUnitBase._apply_equivalencies\u001b[1;34m(self, unit, other, equivalencies)\u001b[0m\n\u001b[0;32m 1020\u001b[0m other_str \u001b[39m=\u001b[39m get_err_str(other)\n\u001b[1;32m-> 1022\u001b[0m \u001b[39mraise\u001b[39;00m UnitConversionError(\n\u001b[0;32m 1023\u001b[0m \u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39m{\u001b[39;00munit_str\u001b[39m}\u001b[39;00m\u001b[39m and \u001b[39m\u001b[39m{\u001b[39;00mother_str\u001b[39m}\u001b[39;00m\u001b[39m are not convertible\u001b[39m\u001b[39m\"\u001b[39m)\n", - "\u001b[1;31mUnitConversionError\u001b[0m: 'km nm / mm' (length) and 'km um' (area) are not convertible", - "\nDuring handling of the above exception, another exception occurred:\n", - "\u001b[1;31mUnitConversionError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\tradebooks\\spatial_resolution_&_swath_vs_focal_length_trade.ipynb Cell 10\u001b[0m line \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[0m sensor_spatial_resolution \u001b[39m=\u001b[39m payload\u001b[39m.\u001b[39;49mget_spatial_resolution(\n\u001b[0;32m 2\u001b[0m wavelength\u001b[39m=\u001b[39;49mtarget_wavelength,\n\u001b[0;32m 3\u001b[0m target_distance\u001b[39m=\u001b[39;49morbital_altitude,\n\u001b[0;32m 4\u001b[0m skew_angle\u001b[39m=\u001b[39;49mskew_angle[\u001b[39m0\u001b[39;49m],\n\u001b[0;32m 5\u001b[0m )\u001b[39m.\u001b[39mto(unit\u001b[39m.\u001b[39mm)\n\u001b[0;32m 7\u001b[0m display(\n\u001b[0;32m 8\u001b[0m \u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mSensor-limited spatial resolution test shape: \u001b[39m\u001b[39m{\u001b[39;00msensor_spatial_resolution\u001b[39m.\u001b[39mshape\u001b[39m}\u001b[39;00m\u001b[39m\"\u001b[39m\n\u001b[0;32m 9\u001b[0m )\n\u001b[0;32m 11\u001b[0m swath \u001b[39m=\u001b[39m payload\u001b[39m.\u001b[39mget_swath(altitude\u001b[39m=\u001b[39morbital_altitude, skew_angle\u001b[39m=\u001b[39mskew_angle)\n", - "File \u001b[1;32m~\\Documents\\GitHub\\architect\\architect\\systems\\optical\\spectrometers.py:280\u001b[0m, in \u001b[0;36mHyperspectralImager.get_spatial_resolution\u001b[1;34m(self, wavelength, target_distance, skew_angle)\u001b[0m\n\u001b[0;32m 270\u001b[0m sensor_spatial_resolution \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mget_sensor_spatial_resolution(\n\u001b[0;32m 271\u001b[0m target_distance\u001b[39m=\u001b[39mtarget_distance\n\u001b[0;32m 272\u001b[0m )\n\u001b[0;32m 274\u001b[0m optical_spatial_resolution \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mget_optical_spatial_resolution(\n\u001b[0;32m 275\u001b[0m wavelength\u001b[39m=\u001b[39mwavelength,\n\u001b[0;32m 276\u001b[0m target_distance\u001b[39m=\u001b[39mtarget_distance,\n\u001b[0;32m 277\u001b[0m skew_angle\u001b[39m=\u001b[39mskew_angle,\n\u001b[0;32m 278\u001b[0m )\n\u001b[1;32m--> 280\u001b[0m spatial_resolution \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39;49mmaximum(\n\u001b[0;32m 281\u001b[0m sensor_spatial_resolution, optical_spatial_resolution\n\u001b[0;32m 282\u001b[0m )\n\u001b[0;32m 284\u001b[0m \u001b[39mreturn\u001b[39;00m spatial_resolution\n", - "File \u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\.venv\\lib\\site-packages\\astropy\\units\\quantity.py:591\u001b[0m, in \u001b[0;36mQuantity.__array_ufunc__\u001b[1;34m(self, function, method, *inputs, **kwargs)\u001b[0m\n\u001b[0;32m 569\u001b[0m \u001b[39m\"\"\"Wrap numpy ufuncs, taking care of units.\u001b[39;00m\n\u001b[0;32m 570\u001b[0m \n\u001b[0;32m 571\u001b[0m \u001b[39mParameters\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 585\u001b[0m \u001b[39m Results of the ufunc, with the unit set properly.\u001b[39;00m\n\u001b[0;32m 586\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[0;32m 587\u001b[0m \u001b[39m# Determine required conversion functions -- to bring the unit of the\u001b[39;00m\n\u001b[0;32m 588\u001b[0m \u001b[39m# input to that expected (e.g., radian for np.sin), or to get\u001b[39;00m\n\u001b[0;32m 589\u001b[0m \u001b[39m# consistent units between two inputs (e.g., in np.add) --\u001b[39;00m\n\u001b[0;32m 590\u001b[0m \u001b[39m# and the unit of the result (or tuple of units for nout > 1).\u001b[39;00m\n\u001b[1;32m--> 591\u001b[0m converters, unit \u001b[39m=\u001b[39m converters_and_unit(function, method, \u001b[39m*\u001b[39;49minputs)\n\u001b[0;32m 593\u001b[0m out \u001b[39m=\u001b[39m kwargs\u001b[39m.\u001b[39mget(\u001b[39m'\u001b[39m\u001b[39mout\u001b[39m\u001b[39m'\u001b[39m, \u001b[39mNone\u001b[39;00m)\n\u001b[0;32m 594\u001b[0m \u001b[39m# Avoid loop back by turning any Quantity output into array views.\u001b[39;00m\n", - "File \u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\.venv\\lib\\site-packages\\astropy\\units\\quantity_helper\\converters.py:174\u001b[0m, in \u001b[0;36mconverters_and_unit\u001b[1;34m(function, method, *args)\u001b[0m\n\u001b[0;32m 171\u001b[0m units \u001b[39m=\u001b[39m [\u001b[39mgetattr\u001b[39m(arg, \u001b[39m'\u001b[39m\u001b[39munit\u001b[39m\u001b[39m'\u001b[39m, \u001b[39mNone\u001b[39;00m) \u001b[39mfor\u001b[39;00m arg \u001b[39min\u001b[39;00m args]\n\u001b[0;32m 173\u001b[0m \u001b[39m# Determine possible conversion functions, and the result unit.\u001b[39;00m\n\u001b[1;32m--> 174\u001b[0m converters, result_unit \u001b[39m=\u001b[39m ufunc_helper(function, \u001b[39m*\u001b[39;49munits)\n\u001b[0;32m 176\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39many\u001b[39m(converter \u001b[39mis\u001b[39;00m \u001b[39mFalse\u001b[39;00m \u001b[39mfor\u001b[39;00m converter \u001b[39min\u001b[39;00m converters):\n\u001b[0;32m 177\u001b[0m \u001b[39m# for multi-argument ufuncs with a quantity and a non-quantity,\u001b[39;00m\n\u001b[0;32m 178\u001b[0m \u001b[39m# the quantity normally needs to be dimensionless, *except*\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 181\u001b[0m \u001b[39m# can just have the unit of the quantity\u001b[39;00m\n\u001b[0;32m 182\u001b[0m \u001b[39m# (this allows, e.g., `q > 0.` independent of unit)\u001b[39;00m\n\u001b[0;32m 183\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m 184\u001b[0m \u001b[39m# Don't fold this loop in the test above: this rare case\u001b[39;00m\n\u001b[0;32m 185\u001b[0m \u001b[39m# should not make the common case slower.\u001b[39;00m\n", - "File \u001b[1;32mc:\\Users\\Optics\\Documents\\GitHub\\architect\\.venv\\lib\\site-packages\\astropy\\units\\quantity_helper\\helpers.py:70\u001b[0m, in \u001b[0;36mget_converters_and_unit\u001b[1;34m(f, unit1, unit2)\u001b[0m\n\u001b[0;32m 68\u001b[0m converters[changeable] \u001b[39m=\u001b[39m get_converter(unit2, unit1)\n\u001b[0;32m 69\u001b[0m \u001b[39mexcept\u001b[39;00m UnitsError:\n\u001b[1;32m---> 70\u001b[0m \u001b[39mraise\u001b[39;00m UnitConversionError(\n\u001b[0;32m 71\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mCan only apply \u001b[39m\u001b[39m'\u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m function to quantities \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m 72\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mwith compatible dimensions\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[0;32m 73\u001b[0m \u001b[39m.\u001b[39mformat(f\u001b[39m.\u001b[39m\u001b[39m__name__\u001b[39m))\n\u001b[0;32m 75\u001b[0m \u001b[39mreturn\u001b[39;00m converters, unit1\n", - "\u001b[1;31mUnitConversionError\u001b[0m: Can only apply 'maximum' function to quantities with compatible dimensions" - ] + "data": { + "text/plain": [ + "'Sensor-limited spatial resolution test shape: (29, 2)'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Swath shape: (29, 2)'" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ @@ -166,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 39, "metadata": {}, "outputs": [ { @@ -424,9 +429,6 @@ }, "tracegroupgap": 0 }, - "margin": { - "t": 60 - }, "template": { "data": { "bar": [ @@ -1252,6 +1254,9 @@ } } }, + "title": { + "text": "Spatial Resolution and Swath vs. Focal Length" + }, "xaxis": { "anchor": "y", "domain": [ @@ -1614,15 +1619,50 @@ " None\n", " \n", " \n", - " components\n", + " systems\n", " list [4]\n", " None\n", " \n", + " \n", + " dimensions\n", + " None\n", + " None\n", + " \n", + " \n", + " mass\n", + " None\n", + " None\n", + " \n", + " \n", + " volume\n", + " None\n", + " None\n", + " \n", + " \n", + " density\n", + " None\n", + " None\n", + " \n", + " \n", + " index\n", + " None\n", + " None\n", + " \n", + " \n", + " transmittance\n", + " None\n", + " None\n", + " \n", + " \n", + " spatial_resolution\n", + " None\n", + " None\n", + " \n", " \n", "" ], "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -1655,7 +1695,7 @@ " swath_label_x,\n", " swath_label_y,\n", " ],\n", - " title=None,\n", + " title=\"Spatial Resolution and Swath vs. Focal Length\",\n", " dark=True,\n", ")\n", "\n",