diff --git a/notebooks/pointing_accuracy_vs_spatial_resolution_tradebook.ipynb b/notebooks/pointing_accuracy_vs_spatial_resolution_tradebook.ipynb new file mode 100644 index 0000000..3770925 --- /dev/null +++ b/notebooks/pointing_accuracy_vs_spatial_resolution_tradebook.ipynb @@ -0,0 +1,3158 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Pointing Accuracy Constraint vs Spatial Resolution" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# external\n", + "import astropy.units as unit\n", + "import numpy as np\n", + "import pandas as pd\n", + "import plot\n", + "from IPython.display import display\n", + "\n", + "# project\n", + "from payload_designer import components, systems" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "Run this section onwards when a parameter is updated." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# region constants\n", + "target_wavelength = 1600 * unit.nm\n", + "orbital_altitude = 600 * unit.km\n", + "\n", + "# endregion\n", + "\n", + "# region variables\n", + "spatial_resolution = np.arange(start=0, stop=100000, step=100) * unit.m\n", + "# endregion" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Artifact Instantiation" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "# region systems\n", + "payload = systems.payloads.HyperspectralImager(spatial_resolution=spatial_resolution)\n", + "# endregion" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pipeline\n", + "The computational graph" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "pointing_constraint = payload.get_pointing_accuracy_constraint(\n", + " wavelength=target_wavelength, target_distance=orbital_altitude\n", + ").to(unit.degree)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plots" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Spatial Resolution [m]=%{x}
Pointing Accuracy Constraint [deg]=%{y}", + "legendgroup": "", + "line": { + "color": "#636efa", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines", + "name": "", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": [ + 0, + 100, + 200, + 300, + 400, + 500, + 600, + 700, + 800, + 900, + 1000, + 1100, + 1200, + 1300, + 1400, + 1500, + 1600, + 1700, + 1800, + 1900, + 2000, + 2100, + 2200, + 2300, + 2400, + 2500, + 2600, + 2700, + 2800, + 2900, + 3000, + 3100, + 3200, + 3300, + 3400, + 3500, + 3600, + 3700, + 3800, + 3900, + 4000, + 4100, + 4200, + 4300, + 4400, + 4500, + 4600, + 4700, + 4800, + 4900, + 5000, + 5100, + 5200, + 5300, + 5400, + 5500, + 5600, + 5700, + 5800, + 5900, + 6000, + 6100, + 6200, + 6300, + 6400, + 6500, + 6600, + 6700, + 6800, + 6900, + 7000, + 7100, + 7200, + 7300, + 7400, + 7500, + 7600, + 7700, + 7800, + 7900, + 8000, + 8100, + 8200, + 8300, + 8400, + 8500, + 8600, + 8700, + 8800, + 8900, + 9000, + 9100, + 9200, + 9300, + 9400, + 9500, + 9600, + 9700, + 9800, + 9900, + 10000, + 10100, + 10200, + 10300, + 10400, + 10500, + 10600, + 10700, + 10800, + 10900, + 11000, + 11100, + 11200, + 11300, + 11400, + 11500, + 11600, + 11700, + 11800, + 11900, + 12000, + 12100, + 12200, + 12300, + 12400, + 12500, + 12600, + 12700, + 12800, + 12900, + 13000, + 13100, + 13200, + 13300, + 13400, + 13500, + 13600, + 13700, + 13800, + 13900, + 14000, + 14100, + 14200, + 14300, + 14400, + 14500, + 14600, + 14700, + 14800, + 14900, + 15000, + 15100, + 15200, + 15300, + 15400, + 15500, + 15600, + 15700, + 15800, + 15900, + 16000, + 16100, + 16200, + 16300, + 16400, + 16500, + 16600, + 16700, + 16800, + 16900, + 17000, + 17100, + 17200, + 17300, + 17400, + 17500, + 17600, + 17700, + 17800, + 17900, + 18000, + 18100, + 18200, + 18300, + 18400, + 18500, + 18600, + 18700, + 18800, + 18900, + 19000, + 19100, + 19200, + 19300, + 19400, + 19500, + 19600, + 19700, + 19800, + 19900, + 20000, + 20100, + 20200, + 20300, + 20400, + 20500, + 20600, + 20700, + 20800, + 20900, + 21000, + 21100, + 21200, + 21300, + 21400, + 21500, + 21600, + 21700, + 21800, + 21900, + 22000, + 22100, + 22200, + 22300, + 22400, + 22500, + 22600, + 22700, + 22800, + 22900, + 23000, + 23100, + 23200, + 23300, + 23400, + 23500, + 23600, + 23700, + 23800, + 23900, + 24000, + 24100, + 24200, + 24300, + 24400, + 24500, + 24600, + 24700, + 24800, + 24900, + 25000, + 25100, + 25200, + 25300, + 25400, + 25500, + 25600, + 25700, + 25800, + 25900, + 26000, + 26100, + 26200, + 26300, + 26400, + 26500, + 26600, + 26700, + 26800, + 26900, + 27000, + 27100, + 27200, + 27300, + 27400, + 27500, + 27600, + 27700, + 27800, + 27900, + 28000, + 28100, + 28200, + 28300, + 28400, + 28500, + 28600, + 28700, + 28800, + 28900, + 29000, + 29100, + 29200, + 29300, + 29400, + 29500, + 29600, + 29700, + 29800, + 29900, + 30000, + 30100, + 30200, + 30300, + 30400, + 30500, + 30600, + 30700, + 30800, + 30900, + 31000, + 31100, + 31200, + 31300, + 31400, + 31500, + 31600, + 31700, + 31800, + 31900, + 32000, + 32100, + 32200, + 32300, + 32400, + 32500, + 32600, + 32700, + 32800, + 32900, + 33000, + 33100, + 33200, + 33300, + 33400, + 33500, + 33600, + 33700, + 33800, + 33900, + 34000, + 34100, + 34200, + 34300, + 34400, + 34500, + 34600, + 34700, + 34800, + 34900, + 35000, + 35100, + 35200, + 35300, + 35400, + 35500, + 35600, + 35700, + 35800, + 35900, + 36000, + 36100, + 36200, + 36300, + 36400, + 36500, + 36600, + 36700, + 36800, + 36900, + 37000, + 37100, + 37200, + 37300, + 37400, + 37500, + 37600, + 37700, + 37800, + 37900, + 38000, + 38100, + 38200, + 38300, + 38400, + 38500, + 38600, + 38700, + 38800, + 38900, + 39000, + 39100, + 39200, + 39300, + 39400, + 39500, + 39600, + 39700, + 39800, + 39900, + 40000, + 40100, + 40200, + 40300, + 40400, + 40500, + 40600, + 40700, + 40800, + 40900, + 41000, + 41100, + 41200, + 41300, + 41400, + 41500, + 41600, + 41700, + 41800, + 41900, + 42000, + 42100, + 42200, + 42300, + 42400, + 42500, + 42600, + 42700, + 42800, + 42900, + 43000, + 43100, + 43200, + 43300, + 43400, + 43500, + 43600, + 43700, + 43800, + 43900, + 44000, + 44100, + 44200, + 44300, + 44400, + 44500, + 44600, + 44700, + 44800, + 44900, + 45000, + 45100, + 45200, + 45300, + 45400, + 45500, + 45600, + 45700, + 45800, + 45900, + 46000, + 46100, + 46200, + 46300, + 46400, + 46500, + 46600, + 46700, + 46800, + 46900, + 47000, + 47100, + 47200, + 47300, + 47400, + 47500, + 47600, + 47700, + 47800, + 47900, + 48000, + 48100, + 48200, + 48300, + 48400, + 48500, + 48600, + 48700, + 48800, + 48900, + 49000, + 49100, + 49200, + 49300, + 49400, + 49500, + 49600, + 49700, + 49800, + 49900, + 50000, + 50100, + 50200, + 50300, + 50400, + 50500, + 50600, + 50700, + 50800, + 50900, + 51000, + 51100, + 51200, + 51300, + 51400, + 51500, + 51600, + 51700, + 51800, + 51900, + 52000, + 52100, + 52200, + 52300, + 52400, + 52500, + 52600, + 52700, + 52800, + 52900, + 53000, + 53100, + 53200, + 53300, + 53400, + 53500, + 53600, + 53700, + 53800, + 53900, + 54000, + 54100, + 54200, + 54300, + 54400, + 54500, + 54600, + 54700, + 54800, + 54900, + 55000, + 55100, + 55200, + 55300, + 55400, + 55500, + 55600, + 55700, + 55800, + 55900, + 56000, + 56100, + 56200, + 56300, + 56400, + 56500, + 56600, + 56700, + 56800, + 56900, + 57000, + 57100, + 57200, + 57300, + 57400, + 57500, + 57600, + 57700, + 57800, + 57900, + 58000, + 58100, + 58200, + 58300, + 58400, + 58500, + 58600, + 58700, + 58800, + 58900, + 59000, + 59100, + 59200, + 59300, + 59400, + 59500, + 59600, + 59700, + 59800, + 59900, + 60000, + 60100, + 60200, + 60300, + 60400, + 60500, + 60600, + 60700, + 60800, + 60900, + 61000, + 61100, + 61200, + 61300, + 61400, + 61500, + 61600, + 61700, + 61800, + 61900, + 62000, + 62100, + 62200, + 62300, + 62400, + 62500, + 62600, + 62700, + 62800, + 62900, + 63000, + 63100, + 63200, + 63300, + 63400, + 63500, + 63600, + 63700, + 63800, + 63900, + 64000, + 64100, + 64200, + 64300, + 64400, + 64500, + 64600, + 64700, + 64800, + 64900, + 65000, + 65100, + 65200, + 65300, + 65400, + 65500, + 65600, + 65700, + 65800, + 65900, + 66000, + 66100, + 66200, + 66300, + 66400, + 66500, + 66600, + 66700, + 66800, + 66900, + 67000, + 67100, + 67200, + 67300, + 67400, + 67500, + 67600, + 67700, + 67800, + 67900, + 68000, + 68100, + 68200, + 68300, + 68400, + 68500, + 68600, + 68700, + 68800, + 68900, + 69000, + 69100, + 69200, + 69300, + 69400, + 69500, + 69600, + 69700, + 69800, + 69900, + 70000, + 70100, + 70200, + 70300, + 70400, + 70500, + 70600, + 70700, + 70800, + 70900, + 71000, + 71100, + 71200, + 71300, + 71400, + 71500, + 71600, + 71700, + 71800, + 71900, + 72000, + 72100, + 72200, + 72300, + 72400, + 72500, + 72600, + 72700, + 72800, + 72900, + 73000, + 73100, + 73200, + 73300, + 73400, + 73500, + 73600, + 73700, + 73800, + 73900, + 74000, + 74100, + 74200, + 74300, + 74400, + 74500, + 74600, + 74700, + 74800, + 74900, + 75000, + 75100, + 75200, + 75300, + 75400, + 75500, + 75600, + 75700, + 75800, + 75900, + 76000, + 76100, + 76200, + 76300, + 76400, + 76500, + 76600, + 76700, + 76800, + 76900, + 77000, + 77100, + 77200, + 77300, + 77400, + 77500, + 77600, + 77700, + 77800, + 77900, + 78000, + 78100, + 78200, + 78300, + 78400, + 78500, + 78600, + 78700, + 78800, + 78900, + 79000, + 79100, + 79200, + 79300, + 79400, + 79500, + 79600, + 79700, + 79800, + 79900, + 80000, + 80100, + 80200, + 80300, + 80400, + 80500, + 80600, + 80700, + 80800, + 80900, + 81000, + 81100, + 81200, + 81300, + 81400, + 81500, + 81600, + 81700, + 81800, + 81900, + 82000, + 82100, + 82200, + 82300, + 82400, + 82500, + 82600, + 82700, + 82800, + 82900, + 83000, + 83100, + 83200, + 83300, + 83400, + 83500, + 83600, + 83700, + 83800, + 83900, + 84000, + 84100, + 84200, + 84300, + 84400, + 84500, + 84600, + 84700, + 84800, + 84900, + 85000, + 85100, + 85200, + 85300, + 85400, + 85500, + 85600, + 85700, + 85800, + 85900, + 86000, + 86100, + 86200, + 86300, + 86400, + 86500, + 86600, + 86700, + 86800, + 86900, + 87000, + 87100, + 87200, + 87300, + 87400, + 87500, + 87600, + 87700, + 87800, + 87900, + 88000, + 88100, + 88200, + 88300, + 88400, + 88500, + 88600, + 88700, + 88800, + 88900, + 89000, + 89100, + 89200, + 89300, + 89400, + 89500, + 89600, + 89700, + 89800, + 89900, + 90000, + 90100, + 90200, + 90300, + 90400, + 90500, + 90600, + 90700, + 90800, + 90900, + 91000, + 91100, + 91200, + 91300, + 91400, + 91500, + 91600, + 91700, + 91800, + 91900, + 92000, + 92100, + 92200, + 92300, + 92400, + 92500, + 92600, + 92700, + 92800, + 92900, + 93000, + 93100, + 93200, + 93300, + 93400, + 93500, + 93600, + 93700, + 93800, + 93900, + 94000, + 94100, + 94200, + 94300, + 94400, + 94500, + 94600, + 94700, + 94800, + 94900, + 95000, + 95100, + 95200, + 95300, + 95400, + 95500, + 95600, + 95700, + 95800, + 95900, + 96000, + 96100, + 96200, + 96300, + 96400, + 96500, + 96600, + 96700, + 96800, + 96900, + 97000, + 97100, + 97200, + 97300, + 97400, + 97500, + 97600, + 97700, + 97800, + 97900, + 98000, + 98100, + 98200, + 98300, + 98400, + 98500, + 98600, + 98700, + 98800, + 98900, + 99000, + 99100, + 99200, + 99300, + 99400, + 99500, + 99600, + 99700, + 99800, + 99900 + ], + "xaxis": "x", + "y": [ + 0, + 0.0047746482817044335, + 0.009549296497094309, + 0.014323944579855075, + 0.019098592463672185, + 0.02387324008223112, + 0.028647887369217372, + 0.033422534258316476, + 0.03819718068321397, + 0.04297182657759547, + 0.04774647187514661, + 0.05252111650955307, + 0.057295760414500616, + 0.06207040352367503, + 0.06684504577076222, + 0.07161968708944809, + 0.07639432741341867, + 0.08116896667636012, + 0.08594360481195855, + 0.0907182417539003, + 0.09549287743587175, + 0.10026751179155938, + 0.10504214475464979, + 0.10981677625882971, + 0.11459140623778596, + 0.11936603462520558, + 0.12414066135477553, + 0.1289152863601832, + 0.13368990957511584, + 0.13846453093326105, + 0.14323915036830656, + 0.14801376781394016, + 0.1527883832038498, + 0.15756299647172375, + 0.1623376075512504, + 0.16711221637611817, + 0.17188682288001592, + 0.1766614269966325, + 0.181436028659657, + 0.1862106278027788, + 0.19098522435968746, + 0.19575981826407265, + 0.20053440944962445, + 0.20530899785003298, + 0.21008358339898867, + 0.2148581660301822, + 0.21963274567730456, + 0.2244073222740468, + 0.22918189575410042, + 0.23395646605115697, + 0.2387310330989086, + 0.2435055968310473, + 0.24828015718126567, + 0.2530547140832565, + 0.25782926747071283, + 0.2626038172773279, + 0.26737836343679555, + 0.2721529058828096, + 0.27692744454906426, + 0.28170197936925434, + 0.2864765102770745, + 0.29125103720622003, + 0.29602556009038655, + 0.3008000788632698, + 0.3055745934585662, + 0.31034910380997227, + 0.3151236098511848, + 0.3198981115159013, + 0.3246726087378194, + 0.32944710145063694, + 0.3342215895880525, + 0.33899607308376484, + 0.3437705518714731, + 0.34854502588487685, + 0.3533194950576761, + 0.35809395932357113, + 0.36286841861626273, + 0.3676428728694522, + 0.372417322016841, + 0.3771917659921313, + 0.3819662047290255, + 0.38674063816122645, + 0.39151506622243754, + 0.39628948884636267, + 0.4010639059667059, + 0.40583831751717203, + 0.41061272343146626, + 0.41538712364329416, + 0.4201615180863619, + 0.424935906694376, + 0.42971028940104355, + 0.4344846661400723, + 0.4392590368451701, + 0.4440334014500455, + 0.44880775988840776, + 0.4535821120939664, + 0.4583564580004315, + 0.46313079754151376, + 0.4679051306509241, + 0.4726794572623747, + 0.47745377730957744, + 0.48222809072624506, + 0.48700239744609125, + 0.49177669740282953, + 0.4965509905301746, + 0.5013252767618416, + 0.5060995560315458, + 0.5108738282730035, + 0.5156480934199319, + 0.5204223514060476, + 0.5251966021650691, + 0.529970845630715, + 0.5347450817367042, + 0.5395193104167566, + 0.5442935316045925, + 0.5490677452339332, + 0.5538419512385, + 0.5586161495520156, + 0.5633903401082025, + 0.5681645228407844, + 0.5729386976834859, + 0.5777128645700316, + 0.5824870234341468, + 0.5872611742095583, + 0.5920353168299926, + 0.5968094512291771, + 0.6015835773408406, + 0.6063576950987116, + 0.6111318044365199, + 0.6159059052879959, + 0.6206799975868706, + 0.6254540812668758, + 0.6302281562617439, + 0.6350022225052082, + 0.6397762799310026, + 0.6445503284728616, + 0.6493243680645211, + 0.6540983986397167, + 0.6588724201321855, + 0.6636464324756655, + 0.6684204356038944, + 0.6731944294506121, + 0.6779684139495583, + 0.6827423890344736, + 0.6875163546390998, + 0.6922903106971791, + 0.6970642571424543, + 0.7018381939086699, + 0.7066121209295704, + 0.711386038138901, + 0.7161599454704085, + 0.7209338428578398, + 0.7257077302349431, + 0.7304816075354671, + 0.7352554746931614, + 0.7400293316417766, + 0.7448031783150643, + 0.7495770146467764, + 0.7543508405706661, + 0.7591246560204874, + 0.7638984609299951, + 0.7686722552329448, + 0.7734460388630932, + 0.7782198117541979, + 0.7829935738400169, + 0.7877673250543098, + 0.7925410653308368, + 0.7973147946033585, + 0.8020885128056375, + 0.8068622198714367, + 0.8116359157345193, + 0.8164096003286508, + 0.8211832735875968, + 0.8259569354451235, + 0.830730585834999, + 0.8355042246909917, + 0.8402778519468711, + 0.8450514675364078, + 0.8498250713933732, + 0.8545986634515397, + 0.8593722436446808, + 0.864145811906571, + 0.8689193681709857, + 0.8736929123717011, + 0.8784664444424949, + 0.8832399643171452, + 0.8880134719294318, + 0.892786967213135, + 0.897560450102036, + 0.9023339205299178, + 0.9071073784305639, + 0.9118808237377585, + 0.9166542563852877, + 0.9214276763069379, + 0.9262010834364973, + 0.9309744777077542, + 0.9357478590544985, + 0.9405212274105219, + 0.9452945827096156, + 0.9500679248855731, + 0.9548412538721889, + 0.9596145696032577, + 0.9643878720125764, + 0.9691611610339427, + 0.9739344366011552, + 0.9787076986480131, + 0.983480947108318, + 0.9882541819158717, + 0.9930274030044769, + 0.9978006103079389, + 1.0025738037600627, + 1.0073469832946544, + 1.0121201488455225, + 1.0168933003464757, + 1.021666437731324, + 1.026439560933879, + 1.031212669887953, + 1.0359857645273594, + 1.0407588447859133, + 1.0455319105974308, + 1.050304961895729, + 1.0550779986146266, + 1.0598510206879428, + 1.0646240280494992, + 1.0693970206331174, + 1.0741699983726205, + 1.0789429612018338, + 1.0837159090545827, + 1.088488841864694, + 1.0932617595659966, + 1.09803466209232, + 1.1028075493774945, + 1.1075804213553526, + 1.1123532779597283, + 1.1171261191244548, + 1.1218989447833692, + 1.1266717548703085, + 1.131444549319111, + 1.1362173280636163, + 1.1409900910376667, + 1.1457628381751035, + 1.1505355694097708, + 1.155308284675514, + 1.160080983906179, + 1.1648536670356138, + 1.169626333997668, + 1.1743989847261913, + 1.1791716191550357, + 1.1839442372180549, + 1.1887168388491027, + 1.193489423982035, + 1.1982619925507096, + 1.203034544488985, + 1.2078070797307208, + 1.212579598209779, + 1.2173520998600218, + 1.222124584615314, + 1.2268970524095206, + 1.2316695031765093, + 1.2364419368501478, + 1.2412143533643065, + 1.245986752652857, + 1.250759134649671, + 1.2555314992886235, + 1.2603038465035896, + 1.2650761762284468, + 1.2698484883970735, + 1.2746207829433494, + 1.2793930598011563, + 1.284165318904377, + 1.2889375601868953, + 1.2937097835825981, + 1.2984819890253725, + 1.3032541764491066, + 1.3080263457876915, + 1.3127984969750188, + 1.317570629944982, + 1.3223427446314757, + 1.3271148409683968, + 1.3318869188896427, + 1.3366589783291132, + 1.3414310192207095, + 1.3462030414983333, + 1.3509750450958895, + 1.3557470299472838, + 1.3605189959864226, + 1.3652909431472153, + 1.3700628713635725, + 1.3748347805694052, + 1.3796066706986276, + 1.3843785416851553, + 1.3891503934629035, + 1.3939222259657913, + 1.3986940391277392, + 1.4034658328826675, + 1.4082376071645, + 1.4130093619071615, + 1.417781097044578, + 1.4225528125106777, + 1.42732450823939, + 1.4320961841646465, + 1.4368678402203796, + 1.4416394763405245, + 1.4464110924590172, + 1.4511826885097951, + 1.4559542644267984, + 1.4607258201439681, + 1.4654973555952469, + 1.4702688707145795, + 1.4750403654359123, + 1.479811839693193, + 1.484583293420372, + 1.4893547265513998, + 1.4941261390202298, + 1.498897530760817, + 1.5036689017071179, + 1.5084402517930908, + 1.5132115809526954, + 1.5179828891198937, + 1.5227541762286492, + 1.527525442212927, + 1.5322966870066943, + 1.5370679105439198, + 1.541839112758574, + 1.546610293584629, + 1.5513814529560592, + 1.5561525908068405, + 1.5609237070709503, + 1.565694801682368, + 1.5704658745750752, + 1.5752369256830545, + 1.5800079549402912, + 1.584778962280772, + 1.589549947638485, + 1.5943209109474206, + 1.5990918521415713, + 1.603862771154931, + 1.6086336679214952, + 1.6134045423752623, + 1.618175394450231, + 1.6229462240804031, + 1.6277170311997824, + 1.632487815742373, + 1.6372585776421829, + 1.6420293168332207, + 1.6468000332494968, + 1.6515707268250241, + 1.6563413974938177, + 1.6611120451898935, + 1.66588266984727, + 1.6706532713999678, + 1.6754238497820089, + 1.6801944049274176, + 1.6849649367702197, + 1.6897354452444437, + 1.6945059302841192, + 1.6992763918232783, + 1.704046829795955, + 1.7088172441361846, + 1.7135876347780055, + 1.7183580016554572, + 1.7231283447025816, + 1.7278986638534224, + 1.7326689590420248, + 1.7374392302024373, + 1.7422094772687091, + 1.7469797001748921, + 1.75174989885504, + 1.7565200732432085, + 1.761290223273455, + 1.7660603488798399, + 1.7708304499964247, + 1.775600526557273, + 1.780370578496451, + 1.7851406057480266, + 1.7899106082460694, + 1.7946805859246517, + 1.799450538717848, + 1.8042204665597337, + 1.8089903693843872, + 1.8137602471258893, + 1.8185300997183222, + 1.8232999270957697, + 1.8280697291923194, + 1.8328395059420592, + 1.8376092572790808, + 1.8423789831374753, + 1.8471486834513395, + 1.8519183581547705, + 1.8566880071818657, + 1.861457630466729, + 1.8662272279434622, + 1.870996799546171, + 1.8757663452089643, + 1.8805358648659518, + 1.885305358451244, + 1.8900748258989577, + 1.8948442671432082, + 1.8996136821181133, + 1.9043830707577951, + 1.9091524329963767, + 1.913921768767982, + 1.9186910780067397, + 1.9234603606467788, + 1.9282296166222308, + 1.9329988458672311, + 1.9377680483159143, + 1.94253722390242, + 1.947306372560889, + 1.952075494225463, + 1.9568445888302883, + 1.9616136563095126, + 1.9663826965972846, + 1.9711517096277562, + 1.9759206953350827, + 1.98068965365342, + 1.9854585845169266, + 1.9902274878597643, + 1.9949963636160954, + 1.999765211720086, + 2.004534032105904, + 2.0093028247077203, + 2.0140715894597063, + 2.0188403262960377, + 2.0236090351508906, + 2.0283777159584453, + 2.0331463686528837, + 2.0379149931683895, + 2.0426835894391493, + 2.047452157399352, + 2.0522206969831887, + 2.0569892081248526, + 2.0617576907585407, + 2.0665261448184498, + 2.071294570238781, + 2.076062966953738, + 2.0808313348975256, + 2.0855996740043516, + 2.090367984208426, + 2.095136265443962, + 2.099904517645174, + 2.1046727407462793, + 2.109440934681498, + 2.114209099385052, + 2.118977234791166, + 2.1237453408340685, + 2.1285134174479867, + 2.133281464567154, + 2.1380494821258043, + 2.142817470058174, + 2.147585428298503, + 2.1523533567810342, + 2.1571212554400097, + 2.161889124209677, + 2.1666569630242867, + 2.1714247718180886, + 2.1761925505253368, + 2.1809602990802897, + 2.185728017417205, + 2.190495705470345, + 2.195263363173974, + 2.2000309904623583, + 2.2047985872697673, + 2.209566153530473, + 2.2143336891787486, + 2.219101194148873, + 2.223868668375124, + 2.2286361117917837, + 2.233403524333137, + 2.238170905933471, + 2.2429382565270743, + 2.247705576048241, + 2.252472864431264, + 2.257240121610441, + 2.2620073475200733, + 2.266774542094462, + 2.2715417052679125, + 2.2763088369747333, + 2.281075937149234, + 2.2858430057257273, + 2.2906100426385296, + 2.2953770478219586, + 2.3001440212103352, + 2.304910962737983, + 2.3096778723392286, + 2.3144447499483993, + 2.319211595499828, + 2.3239784089278483, + 2.328745190166796, + 2.333511939151012, + 2.3382786558148383, + 2.3430453400926177, + 2.3478119919187, + 2.3525786112274347, + 2.357345197953174, + 2.3621117520302737, + 2.366878273393092, + 2.3716447619759897, + 2.3764112177133314, + 2.381177640539483, + 2.3859440303888126, + 2.3907103871956936, + 2.3954767108944997, + 2.4002430014196086, + 2.4050092587054004, + 2.4097754826862574, + 2.414541673296566, + 2.4193078304707143, + 2.424073954143093, + 2.4288400442480964, + 2.4336061007201217, + 2.438372123493567, + 2.4431381125028357, + 2.447904067682334, + 2.4526699889664667, + 2.457435876289647, + 2.4622017295862877, + 2.4669675487908047, + 2.471733333837618, + 2.476499084661149, + 2.481264801195823, + 2.4860304833760667, + 2.490796131136312, + 2.4955617444109905, + 2.50032732313454, + 2.5050928672413995, + 2.50985837666601, + 2.5146238513428165, + 2.519389291206267, + 2.5241546961908132, + 2.528920066230907, + 2.5336854012610046, + 2.5384507012155666, + 2.543215966029054, + 2.547981195635933, + 2.552746389970671, + 2.5575115489677387, + 2.56227667256161, + 2.5670417606867626, + 2.571806813277675, + 2.5765718302688305, + 2.581336811594715, + 2.5861017571898164, + 2.5908666669886267, + 2.5956315409256403, + 2.6003963789353546, + 2.60516118095227, + 2.60992594691089, + 2.614690676745721, + 2.619455370391272, + 2.624220027782057, + 2.6289846488525894, + 2.6337492335373884, + 2.638513781770976, + 2.643278293487876, + 2.6480427686226156, + 2.6528072071097264, + 2.65757160888374, + 2.662335973879195, + 2.6671003020306303, + 2.6718645932725877, + 2.6766288475396145, + 2.681393064766259, + 2.6861572448870716, + 2.6909213878366094, + 2.695685493549429, + 2.7004495619600917, + 2.705213593003162, + 2.709977586613207, + 2.7147415427247963, + 2.719505461272505, + 2.724269342190909, + 2.7290331854145866, + 2.7337969908781226, + 2.738560758516102, + 2.743324488263113, + 2.74808818005375, + 2.752851833822607, + 2.7576154495042817, + 2.762379027033378, + 2.7671425663444986, + 2.771906067372252, + 2.77666953005125, + 2.7814329543161067, + 2.7861963401014385, + 2.7909596873418674, + 2.795722995972017, + 2.800486265926513, + 2.8052494971399877, + 2.8100126895470736, + 2.814775843082407, + 2.8195389576806282, + 2.8243020332763806, + 2.8290650698043094, + 2.8338280671990654, + 2.838591025395301, + 2.843353944327672, + 2.8481168239308388, + 2.852879664139462, + 2.8576424648882086, + 2.862405226111748, + 2.8671679477447514, + 2.871930629721895, + 2.876693271977858, + 2.8814558744473224, + 2.886218437064973, + 2.8909809597655, + 2.895743442483594, + 2.900505885153951, + 2.90526828771127, + 2.9100306500902517, + 2.914792972225603, + 2.919555254052032, + 2.9243174955042504, + 2.9290796965169736, + 2.9338418570249205, + 2.938603976962813, + 2.943366056265376, + 2.9481280948673394, + 2.952890092703434, + 2.957652049708396, + 2.9624139658169644, + 2.9671758409638804, + 2.97193767508389, + 2.9766994681117436, + 2.981461219982192, + 2.986222930629991, + 2.9909845999899005, + 2.995746227996683, + 3.0005078145851045, + 3.005269359689934, + 3.010030863245945, + 3.014792325187913, + 3.019553745450619, + 3.0243151239688455, + 3.029076460677379, + 3.033837755511009, + 3.038599008404531, + 3.0433602192927403, + 3.048121388110438, + 3.0528825147924286, + 3.057643599273518, + 3.0624046414885187, + 3.067165641372245, + 3.0719265988595135, + 3.076687513885147, + 3.0814483863839706, + 3.0862092162908112, + 3.090970003540502, + 3.0957307480678793, + 3.10049144980778, + 3.1052521086950478, + 3.110012724664529, + 3.114773297651073, + 3.119533827589533, + 3.1242943144147666, + 3.129054758061632, + 3.1338151584649956, + 3.138575515559723, + 3.1433358292806854, + 3.148096099562759, + 3.152856326340821, + 3.1576165095497517, + 3.162376649124439, + 3.167136744999771, + 3.1718967971106387, + 3.176656805391941, + 3.181416769778576, + 3.1861766902054476, + 3.190936566607463, + 3.1956963989195333, + 3.200456187076571, + 3.2052159310134973, + 3.2099756306652316, + 3.214735285966699, + 3.21949489685283, + 3.224254463258556, + 3.229013985118813, + 3.233773462368543, + 3.238532894942688, + 3.243292282776195, + 3.248051625804017, + 3.2528109239611074, + 3.2575701771824237, + 3.2623293854029307, + 3.2670885485575925, + 3.2718476665813783, + 3.276606739409263, + 3.2813657669762226, + 3.2861247492172367, + 3.2908836860672928, + 3.2956425774613773, + 3.300401423334482, + 3.3051602236216038, + 3.309918978257741, + 3.314677687177898, + 3.3194363503170816, + 3.324194967610302, + 3.3289535389925744, + 3.333712064398917, + 3.3384705437643523, + 3.3432289770239065, + 3.3479873641126088, + 3.352745704965493, + 3.357503999517597, + 3.3622622477039616, + 3.3670204494596323, + 3.371778604719657, + 3.37653671341909, + 3.3812947754929863, + 3.3860527908764073, + 3.3908107595044177, + 3.3955686813120844, + 3.40032655623448, + 3.405084384206681, + 3.409842165163766, + 3.414599899040819, + 3.419357585772928, + 3.4241152252951843, + 3.4288728175426826, + 3.433630362450522, + 3.4383878599538065, + 3.4431453099876426, + 3.447902712487141, + 3.452660067387417, + 3.4574173746235877, + 3.462174634130778, + 3.466931845844114, + 3.4716890096987254, + 3.4764461256297468, + 3.481203193572317, + 3.485960213461579, + 3.4907171852326777, + 3.495474108820765, + 3.5002309841609938, + 3.504987811188523, + 3.509744589838515, + 3.5145013200461355, + 3.519258001746555, + 3.524014634874949, + 3.528771219366493, + 3.5335277551563706, + 3.5382842421797696, + 3.5430406803718775, + 3.5477970696678907, + 3.5525534100030067, + 3.5573097013124277, + 3.56206594353136, + 3.5668221365950146, + 3.5715782804386054, + 3.576334374997351, + 3.5810904202064746, + 3.5858464160012016, + 3.590602362316765, + 3.595358259088398, + 3.6001141062513375, + 3.604869903740831, + 3.6096256514921223, + 3.614381349440463, + 3.6191369975211094, + 3.6238925956693198, + 3.628648143820357, + 3.6334036419094917, + 3.6381590898719924, + 3.642914487643136, + 3.647669835158203, + 3.652425132352477, + 3.657180379161246, + 3.661935575519803, + 3.666690721363443, + 3.671445816627471, + 3.676200861247186, + 3.680955855157901, + 3.685710798294928, + 3.690465690593584, + 3.695220531989191, + 3.699975322417077, + 3.7047300618125667, + 3.709484750110998, + 3.71423938724771, + 3.7189939731580433, + 3.723748507777344, + 3.728502991040966, + 3.7332574228842614, + 3.7380118032425913, + 3.742766132051321, + 3.7475204092458156, + 3.7522746347614473, + 3.757028808533596, + 3.7617829304976382, + 3.7665370005889605, + 3.7712910187429536, + 3.7760449848950093, + 3.780798898980525, + 3.785552760934905, + 3.7903065706935526, + 3.79506032819188, + 3.7998140333653043, + 3.8045676861492406, + 3.809321286479114, + 3.814074834290355, + 3.8188283295183916, + 3.8235817720986627, + 3.8283351619666095, + 3.833088499057676, + 3.837841783307312, + 3.842595014650972, + 3.847348193024113, + 3.852101318362198, + 3.856854390600695, + 3.861607409675074, + 3.8663603755208107, + 3.8711132880733867, + 3.8758661472682845, + 3.880618953040993, + 3.8853717053270063, + 3.8901244040618224, + 3.8948770491809412, + 3.899629640619871, + 3.9043821783141235, + 3.90913466219921, + 3.913887092210654, + 3.9186394682839785, + 3.9233917903547106, + 3.9281440583583853, + 3.9328962722305385, + 3.9376484319067124, + 3.942400537322454, + 3.9471525884133127, + 3.951904585114845, + 3.9566565273626093, + 3.961408415092172, + 3.966160248239098, + 3.9709120267389633, + 3.975663750527346, + 3.9804154195398254, + 3.98516703371199, + 3.989918592979431, + 3.9946700972777434, + 3.999421546542527, + 4.004172940709388, + 4.008924279713933, + 4.013675563491778, + 4.01842679197854, + 4.023177965109842, + 4.027929082821312, + 4.03268014504858, + 4.037431151727286, + 4.042182102793067, + 4.04693299818157, + 4.051683837828445, + 4.056434621669348, + 4.0611853496399375, + 4.065936021675876, + 4.070686637712834, + 4.075437197686483, + 4.080187701532502, + 4.084938149186572, + 4.089688540584381, + 4.094438875661618, + 4.099189154353982, + 4.103939376597174, + 4.108689542326896, + 4.113439651478862, + 4.118189703988784, + 4.12293969979238, + 4.1276896388253785, + 4.132439521023504, + 4.137189346322492, + 4.141939114658079, + 4.146688825966009, + 4.151438480182029, + 4.1561880772418895, + 4.160937617081348, + 4.165687099636167, + 4.170436524842112, + 4.175185892634952, + 4.179935202950464, + 4.184684455724429, + 4.189433650892629, + 4.194182788390857, + 4.198931868154905, + 4.203680890120574, + 4.208429854223666, + 4.21317876039999, + 4.217927608585359, + 4.222676398715594, + 4.227425130726513, + 4.2321738045539465, + 4.236922420133728, + 4.241670977401691, + 4.24641947629368, + 4.251167916745542, + 4.255916298693128, + 4.260664622072292, + 4.265412886818899, + 4.270161092868811, + 4.274909240157902, + 4.279657328622045, + 4.284405358197123, + 4.289153328819018, + 4.293901240423623, + 4.298649092946831, + 4.303396886324542, + 4.30814462049266, + 4.312892295387097, + 4.317639910943763, + 4.322387467098581, + 4.327134963787472, + 4.331882400946366, + 4.336629778511198, + 4.341377096417904, + 4.34612435460243, + 4.350871553000723, + 4.355618691548736, + 4.360365770182427, + 4.365112788837761, + 4.369859747450705, + 4.37460664595723, + 4.379353484293316, + 4.384100262394946, + 4.388846980198105, + 4.393593637638789, + 4.398340234652993, + 4.40308677117672, + 4.407833247145979, + 4.412579662496782, + 4.417326017165144, + 4.4220723110870885, + 4.426818544198645, + 4.431564716435844, + 4.436310827734722, + 4.441056878031323, + 4.445802867261693, + 4.450548795361884, + 4.455294662267956, + 4.460040467915967, + 4.464786212241987, + 4.469531895182088, + 4.4742775166723465, + 4.479023076648846, + 4.483768575047674, + 4.488514011804921, + 4.4932593868566855, + 4.498004700139072, + 4.502749951588184, + 4.5074951411401365, + 4.512240268731049, + 4.516985334297041, + 4.52173033777424, + 4.526475279098784, + 4.531220158206804, + 4.535964975034448, + 4.540709729517864, + 4.545454421593201, + 4.550199051196622, + 4.554943618264289, + 4.55968812273237, + 4.5644325645370385, + 4.569176943614475, + 4.573921259900861, + 4.578665513332388, + 4.58340970384525, + 4.588153831375644, + 4.5928978958597755, + 4.597641897233856, + 4.602385835434099, + 4.607129710396724, + 4.611873522057959, + 4.616617270354029, + 4.621360955221173, + 4.626104576595633, + 4.630848134413652, + 4.635591628611481, + 4.64033505912538, + 4.645078425891606, + 4.649821728846429, + 4.65456496792612, + 4.659308143066955, + 4.664051254205216, + 4.6687943012771935, + 4.673537284219177, + 4.678280202967467, + 4.683023057458366, + 4.687765847628181, + 4.692508573413228, + 4.697251234749826, + 4.701993831574297, + 4.706736363822971, + 4.711478831432188, + 4.71622123433828, + 4.720963572477598, + 4.725705845786492, + 4.730448054201316, + 4.735190197658433, + 4.739932276094209, + 4.744674289445015, + 4.749416237647231, + 4.7541581206372365, + 4.758899938351422 + ], + "yaxis": "y" + } + ], + "layout": { + "legend": { + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#f2f5fa" + }, + "error_y": { + "color": "#f2f5fa" + }, + "marker": { + "line": { + "color": "rgb(17,17,17)", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "rgb(17,17,17)", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#A2B1C6", + "gridcolor": "#506784", + "linecolor": "#506784", + "minorgridcolor": "#506784", + "startlinecolor": "#A2B1C6" + }, + "baxis": { + "endlinecolor": "#A2B1C6", + "gridcolor": "#506784", + "linecolor": "#506784", + "minorgridcolor": "#506784", + "startlinecolor": "#A2B1C6" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "line": { + "color": "#283442" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "line": { + "color": "#283442" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#506784" + }, + "line": { + "color": "rgb(17,17,17)" + } + }, + "header": { + "fill": { + "color": "#2a3f5f" + }, + "line": { + "color": "rgb(17,17,17)" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#f2f5fa", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#f2f5fa" + }, + "geo": { + "bgcolor": "rgb(17,17,17)", + "lakecolor": "rgb(17,17,17)", + "landcolor": "rgb(17,17,17)", + "showlakes": true, + "showland": true, + "subunitcolor": "#506784" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "dark" + }, + "paper_bgcolor": "rgb(17,17,17)", + "plot_bgcolor": "rgb(17,17,17)", + "polar": { + "angularaxis": { + "gridcolor": "#506784", + "linecolor": "#506784", + "ticks": "" + }, + "bgcolor": "rgb(17,17,17)", + "radialaxis": { + "gridcolor": "#506784", + "linecolor": "#506784", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "rgb(17,17,17)", + "gridcolor": "#506784", + "gridwidth": 2, + "linecolor": "#506784", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#C8D4E3" + }, + "yaxis": { + "backgroundcolor": "rgb(17,17,17)", + "gridcolor": "#506784", + "gridwidth": 2, + "linecolor": "#506784", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#C8D4E3" + }, + "zaxis": { + "backgroundcolor": "rgb(17,17,17)", + "gridcolor": "#506784", + "gridwidth": 2, + "linecolor": "#506784", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#C8D4E3" + } + }, + "shapedefaults": { + "line": { + "color": "#f2f5fa" + } + }, + "sliderdefaults": { + "bgcolor": "#C8D4E3", + "bordercolor": "rgb(17,17,17)", + "borderwidth": 1, + "tickwidth": 0 + }, + "ternary": { + "aaxis": { + "gridcolor": "#506784", + "linecolor": "#506784", + "ticks": "" + }, + "baxis": { + "gridcolor": "#506784", + "linecolor": "#506784", + "ticks": "" + }, + "bgcolor": "rgb(17,17,17)", + "caxis": { + "gridcolor": "#506784", + "linecolor": "#506784", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "updatemenudefaults": { + "bgcolor": "#506784", + "borderwidth": 0 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#283442", + "linecolor": "#506784", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#283442", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#283442", + "linecolor": "#506784", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#283442", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "FINCH Eye Pointing Accuracy Constraint vs. Spatial Resolution" + }, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Spatial Resolution [m]" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Pointing Accuracy Constraint [deg]" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "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", + "
Spatial Resolution [m]Pointing Accuracy Constraint [deg]
00.00.000000
1100.00.004775
2200.00.009549
3300.00.014324
4400.00.019099
.........
99599500.04.739932
99699600.04.744674
99799700.04.749416
99899800.04.754158
99999900.04.758900
\n", + "

1000 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " Spatial Resolution [m] Pointing Accuracy Constraint [deg]\n", + "0 0.0 0.000000\n", + "1 100.0 0.004775\n", + "2 200.0 0.009549\n", + "3 300.0 0.014324\n", + "4 400.0 0.019099\n", + ".. ... ...\n", + "995 99500.0 4.739932\n", + "996 99600.0 4.744674\n", + "997 99700.0 4.749416\n", + "998 99800.0 4.754158\n", + "999 99900.0 4.758900\n", + "\n", + "[1000 rows x 2 columns]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "spatial_resolution_label = f\"Spatial Resolution [{spatial_resolution.unit}]\"\n", + "pointing_constraint_label = f\"Pointing Accuracy Constraint [{pointing_constraint.unit}]\"\n", + "\n", + "data = {\n", + " spatial_resolution_label: spatial_resolution,\n", + " pointing_constraint_label: pointing_constraint,\n", + "}\n", + "\n", + "df = pd.DataFrame.from_dict(data=data)\n", + "graph = plot.line(\n", + " df=df,\n", + " x=spatial_resolution_label,\n", + " y=pointing_constraint_label,\n", + " title=\"FINCH Eye Pointing Accuracy Constraint vs. Spatial Resolution\",\n", + " dark=True,\n", + ")\n", + "\n", + "graph.show()\n", + "display(df)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "a051636751d8b8c3fb678ae2c2b84596f57742a247cc1675aae9ee3b371aaacc" + }, + "kernelspec": { + "display_name": "Python 3.10.4 ('.venv': poetry)", + "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.4" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/tradebook_template.ipynb b/notebooks/tradebook_template.ipynb new file mode 100644 index 0000000..0965472 --- /dev/null +++ b/notebooks/tradebook_template.ipynb @@ -0,0 +1,129 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Tradebook Template\n", + "Use this notebook as a template to create a tradebook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# imports" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Setup\n", + "Run this section onwards when a parameter is updated." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Parameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# region constants\n", + "\n", + "# endregion\n", + "\n", + "\n", + "# region variables\n", + "\n", + "# endregion" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Artifact Instantiation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# region components\n", + "\n", + "# endregion\n", + "\n", + "\n", + "# region systems\n", + "\n", + "# endregion" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Pipeline\n", + "The computational graph" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plots" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "a051636751d8b8c3fb678ae2c2b84596f57742a247cc1675aae9ee3b371aaacc" + }, + "kernelspec": { + "display_name": "Python 3.10.4 ('.venv': poetry)", + "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.4" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/payload_designer/components/foreoptics.py b/payload_designer/components/foreoptics.py index 7654b27..983d4ad 100644 --- a/payload_designer/components/foreoptics.py +++ b/payload_designer/components/foreoptics.py @@ -144,3 +144,14 @@ def get_image_area(self): a_i = math.pi * (self.d_i / 2) ** 2 return a_i + + +class Chromar(Foreoptic): + def __init__(self): + super().__init__( + diameter=80 * unit.mm, + focal_length=100 * unit.mm, + mass=250 * unit.g, + length=100 * unit.mm, + transmittance=None, + ) diff --git a/payload_designer/systems/payloads.py b/payload_designer/systems/payloads.py index 32c9f69..5a79cc7 100644 --- a/payload_designer/systems/payloads.py +++ b/payload_designer/systems/payloads.py @@ -40,12 +40,14 @@ def get_volume(self): class HyperspectralImager(Payload): def __init__( self, - sensor: Component, - foreoptic: Component, - slit: Component, - diffractor: Component, + spatial_resolution=None, + sensor: Component = None, + foreoptic: Component = None, + slit: Component = None, + diffractor: Component = None, **components: Component, ): + self.spatial_resolution = spatial_resolution super().__init__( sensor=sensor, foreoptic=foreoptic, @@ -107,11 +109,14 @@ def get_FOV(self) -> np.ndarray[float, float]: def get_iFOV(self) -> np.ndarray[float, float]: """Get the instantaneous field of view.""" + assert self.sensor is not None, "A sensor component must be specified." + assert self.foreoptic is not None, "A foreoptic component must be specified." + iFOV = 2 * np.arctan(self.sensor.pitch / (2 * self.foreoptic.focal_length)) return iFOV - def get_sensor_spatial_resolution(self, target_distance, skew_angle): + def get_sensor_spatial_resolution(self, target_distance, skew_angle=0): """Get the sensor-limited spatial resolution.""" iFOV = self.get_iFOV() @@ -141,8 +146,9 @@ def get_swath( return swath - def get_optical_spatial_resolution(self, wavelength, target_distance, skew_angle): + def get_optical_spatial_resolution(self, wavelength, target_distance, skew_angle=0): """Get the optically-limited spatial resolution.""" + assert self.foreoptic is not None, "A foreoptic component must be specified." optical_spatial_resolution = ( 1.22 @@ -152,20 +158,22 @@ def get_optical_spatial_resolution(self, wavelength, target_distance, skew_angle return optical_spatial_resolution - def get_spatial_resolution(self, wavelength, target_distance, skew_angle): - """Get the spatial resolution or ground sample distance of the - system.""" + def get_spatial_resolution(self, wavelength, target_distance, skew_angle=0): + """Get the spatial resolution of the system.""" + if self.spatial_resolution is not None: + return self.spatial_resolution sensor_spatial_resolution = self.get_sensor_spatial_resolution( target_distance=target_distance, skew_angle=skew_angle ) + optical_spatial_resolution = self.get_optical_spatial_resolution( wavelength=wavelength, target_distance=target_distance, skew_angle=skew_angle, ) - spatial_resolution = np.max( + spatial_resolution = np.maximum( sensor_spatial_resolution, optical_spatial_resolution ) @@ -232,6 +240,19 @@ def get_spectral_resolution( return spectral_resolution + def get_pointing_accuracy_constraint( + self, wavelength, target_distance, tolerance=0.5 + ): + """Get the pointing accuracy constraint.""" + + spatial_resolution = self.get_spatial_resolution( + wavelength=wavelength, target_distance=target_distance + ) + + constraint_angle = np.arctan((tolerance * spatial_resolution) / target_distance) + + return constraint_angle + class FINCHEye(HyperspectralImager): def __init__( diff --git a/tests/test_systems/test_payloads/test_HyperspectralImager.py b/tests/test_systems/test_payloads/test_HyperspectralImager.py index da89ad6..678ecbc 100644 --- a/tests/test_systems/test_payloads/test_HyperspectralImager.py +++ b/tests/test_systems/test_payloads/test_HyperspectralImager.py @@ -1,31 +1,87 @@ +# stdlib +import logging +# external import astropy.units as unit import numpy as np -import pandas as pd -import logging -from IPython.display import display # project from payload_designer import components, systems -from payload_designer.libs import utillib +from payload_designer.systems.payloads import HyperspectralImager +LOG = logging.getLogger(__name__) -from payload_designer.components.sensors import TauSWIR -from payload_designer.components.foreoptics import Foreoptic -from payload_designer.systems.payloads import HyperspectralImager +def test_get_optical_spatial_resolution(): + """Test the optically-limited spatial resolution method.""" + + # region params + wavelength = 400 * unit.nm + target_distance = 1 * unit.km + # endregion + + # region instantiation + foreoptic = components.foreoptics.Chromar() + system = HyperspectralImager(foreoptic=foreoptic) + # endregion + + # region pipeline + res = system.get_optical_spatial_resolution( + wavelength=wavelength, target_distance=target_distance + ) + LOG.info(f"Optically-limited spatial resolution: {res}") + # endregion + + +def test_get_sensor_spatial_resolution(): + """Test the sensor-limited spatial resolution method.""" + + # region params + target_distance = 1 * unit.km + # endregion + + # region instantiation + sensor = components.sensors.TauSWIR() + foreoptic = components.foreoptics.Chromar() + system = HyperspectralImager(sensor=sensor, foreoptic=foreoptic) + # endregion + + # region pipeline + res = system.get_sensor_spatial_resolution(target_distance=target_distance) + LOG.info(f"Sensor-limited spatial resolution: {res}") + # endregion + + +def test_get_spatial_resolution(): + """Test the net spatial resolution method.""" + + # region params + wavelength = 400 * unit.nm + target_distance = 1 * unit.km + # endregion + + # region instantiation + sensor = components.sensors.TauSWIR() + foreoptic = components.foreoptics.Chromar() + system = HyperspectralImager(sensor=sensor, foreoptic=foreoptic) + # endregion + + # region pipeline + res = system.get_spatial_resolution( + wavelength=wavelength, target_distance=target_distance + ) + LOG.info(f"Spatial resolution: {res}") + # endregion -LOG = logging.getLogger(__name__) def test_get_optical_spectral_resolution(): - '''Test of get_optical_spectral_resolution function''' + """Test of get_optical_spectral_resolution function.""" target_wavelength = 1650 * unit.nm diameter = 100 * unit.mm slit_size = np.array([3, 1]) * unit.mm focal_length = 100 * unit.mm - fringe_frequency = 600 * (1/unit.mm) - + fringe_frequency = 600 * (1 / unit.mm) sensor = TauSWIR() foreoptic = Foreoptic(diameter=diameter, focal_length=focal_length) @@ -33,10 +89,13 @@ def test_get_optical_spectral_resolution(): sr_grating = components.diffractors.SRTGrating(fringe_frequency=fringe_frequency) - HP = HyperspectralImager(sensor=sensor, foreoptic=foreoptic, slit=slit, diffractor=sr_grating) + HP = HyperspectralImager( + sensor=sensor, foreoptic=foreoptic, slit=slit, diffractor=sr_grating + ) - optical_spectral_resolution = HP.get_optical_spectral_resolution(target_wavelength=target_wavelength, beam_diameter=25*unit.mm) - + optical_spectral_resolution = HP.get_optical_spectral_resolution( + target_wavelength=target_wavelength, beam_diameter=25 * unit.mm + ) LOG.info(f"Optical Specral resolution: {optical_spectral_resolution}") @@ -44,16 +103,14 @@ def test_get_optical_spectral_resolution(): def test_get_sensor_spectral_resolution(): - '''Test of get_optical_spectral_resolution function''' + """Test of get_optical_spectral_resolution function.""" - diameter = 100 * unit.mm upper_wavelength = 1700 * unit.nm lower_wavelength = 900 * unit.nm slit_size = np.array([3, 1]) * unit.mm focal_length = 100 * unit.mm - fringe_frequency = 600 * (1/unit.mm) - + fringe_frequency = 600 * (1 / unit.mm) sensor = TauSWIR() foreoptic = Foreoptic(diameter=diameter, focal_length=focal_length) @@ -61,17 +118,23 @@ def test_get_sensor_spectral_resolution(): sr_grating = components.diffractors.SRTGrating(fringe_frequency=fringe_frequency) - HP = HyperspectralImager(sensor=sensor, foreoptic=foreoptic, slit=slit, diffractor=sr_grating) + HP = HyperspectralImager( + sensor=sensor, foreoptic=foreoptic, slit=slit, diffractor=sr_grating + ) - sensor_spectral_resolution = HP.get_sensor_spectral_resolution(upper_wavelength=upper_wavelength, lower_wavelength=lower_wavelength, beam_diameter=25*unit.mm) - + sensor_spectral_resolution = HP.get_sensor_spectral_resolution( + upper_wavelength=upper_wavelength, + lower_wavelength=lower_wavelength, + beam_diameter=25 * unit.mm, + ) LOG.info(f"Sensor Specral resolution: {sensor_spectral_resolution}") assert sensor_spectral_resolution == 1.5625 * unit.nm + def test_get_spectral_resolution(): - '''Test of get_optical_spectral_resolution function''' + """Test of get_optical_spectral_resolution function.""" target_wavelength = 1650 * unit.nm diameter = 100 * unit.mm @@ -79,8 +142,7 @@ def test_get_spectral_resolution(): lower_wavelength = 900 * unit.nm slit_size = np.array([3, 1]) * unit.mm focal_length = 100 * unit.mm - fringe_frequency = 600 * (1/unit.mm) - + fringe_frequency = 600 * (1 / unit.mm) sensor = TauSWIR() foreoptic = Foreoptic(diameter=diameter, focal_length=focal_length) @@ -88,11 +150,40 @@ def test_get_spectral_resolution(): sr_grating = components.diffractors.SRTGrating(fringe_frequency=fringe_frequency) - HP = HyperspectralImager(sensor=sensor, foreoptic=foreoptic, slit=slit, diffractor=sr_grating) + HP = HyperspectralImager( + sensor=sensor, foreoptic=foreoptic, slit=slit, diffractor=sr_grating + ) - spectral_resolution = HP.get_spectral_resolution(upper_wavelength=upper_wavelength, lower_wavelength=lower_wavelength, target_wavelength=target_wavelength, beam_diameter=[25, 25]*unit.mm) - + spectral_resolution = HP.get_spectral_resolution( + upper_wavelength=upper_wavelength, + lower_wavelength=lower_wavelength, + target_wavelength=target_wavelength, + beam_diameter=[25, 25] * unit.mm, + ) LOG.info(f"Specral resolution: {spectral_resolution}") - assert spectral_resolution == [1.5625, 1.5625] * unit.nm \ No newline at end of file + assert spectral_resolution == [1.5625, 1.5625] * unit.nm + + +def test_get_pointing_accuracy_constraint(): + """Test the get pointing accuracy constraint method.""" + + # region params + wavelength = 400 * unit.nm + target_distance = 1 * unit.km + # endregion + + # region instantiation + sensor = components.sensors.TauSWIR() + foreoptic = components.foreoptics.Chromar() + system = HyperspectralImager(sensor=sensor, foreoptic=foreoptic) + # endregion + + # region pipeline + res = system.get_pointing_accuracy_constraint( + wavelength=wavelength, + target_distance=target_distance, + ) + LOG.info(f"Pointing accuracy constraint: {res}") + # endregion