Browse Source

Copy over work from much earilier expermient.

master
Nathan Bergey 5 years ago
parent
commit
21d08106fc
  1. 2
      .gitignore
  2. 13
      Makefile
  3. 16
      Pipfile
  4. 519
      Pipfile.lock
  5. 10
      README.markdown
  6. 3
      README.md
  7. BIN
      data/L-12_calibration.hdf5
  8. 7
      figures.tpl
  9. 510
      matplotlibrc
  10. 430
      post.ipynb

2
.gitignore

@ -114,3 +114,5 @@ dmypy.json
# Pyre type checker
.pyre/
post_files
*.md

13
Makefile

@ -0,0 +1,13 @@
post.md: post.ipynb
pipenv run jupyter nbconvert --no-input --template=figures.tpl --to=markdown post.ipynb
to_blog: post.md
cp post.md ../../natronics.org/source/_posts/magnetometer_calibration.md
mkdir -p ../../natronics.org/source/_posts/magnetometer_calibration/img
cp img/* ../../natronics.org/source/_posts/magnetometer_calibration/img
cp -r post_files/ ../../natronics.org/source/_posts/magnetometer_calibration/
clean:
rm -rf post_files
rm post.md

16
Pipfile

@ -0,0 +1,16 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
numpy = "*"
matplotlib = "*"
h5py = "*"
jupyter = "*"
scipy = "*"
[requires]
python_version = "3.7"

519
Pipfile.lock

@ -0,0 +1,519 @@
{
"_meta": {
"hash": {
"sha256": "c811927fe358e516a380ba9775720613a237fc0e95292df06ce472090925ceb3"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.7"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"attrs": {
"hashes": [
"sha256:69c0dbf2ed392de1cb5ec704444b08a5ef81680a61cb899dc08127123af36a79",
"sha256:f0b870f674851ecbfbbbd364d6b5cbdff9dcedbc7f3f5e18a6891057f21fe399"
],
"version": "==19.1.0"
},
"backcall": {
"hashes": [
"sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4",
"sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2"
],
"version": "==0.1.0"
},
"bleach": {
"hashes": [
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
],
"version": "==3.1.0"
},
"cycler": {
"hashes": [
"sha256:1d8a5ae1ff6c5cf9b93e8811e581232ad8920aeec647c37316ceac982b08cb2d",
"sha256:cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8"
],
"version": "==0.10.0"
},
"decorator": {
"hashes": [
"sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de",
"sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6"
],
"version": "==4.4.0"
},
"defusedxml": {
"hashes": [
"sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93",
"sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5"
],
"version": "==0.6.0"
},
"entrypoints": {
"hashes": [
"sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
"sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
],
"version": "==0.3"
},
"h5py": {
"hashes": [
"sha256:05750b91640273c69989c657eaac34b091abdd75efc8c4824c82aaf898a2da0a",
"sha256:082a27208aa3a2286e7272e998e7e225b2a7d4b7821bd840aebf96d50977abbb",
"sha256:08e2e8297195f9e813e894b6c63f79372582787795bba2014a2db6a2de95f713",
"sha256:0dd2adeb2e9de5081eb8dcec88874e7fd35dae9a21557be3a55a3c7d491842a4",
"sha256:0f94de7a10562b991967a66bbe6dda9808e18088676834c0a4dcec3fdd3bcc6f",
"sha256:106e42e2e01e486a3d32eeb9ba0e3a7f65c12fa8998d63625fa41fb8bdc44cdb",
"sha256:1606c66015f04719c41a9863c156fc0e6b992150de21c067444bcb82e7d75579",
"sha256:1854c4beff9961e477e133143c5e5e355dac0b3ebf19c52cf7cc1b1ef757703c",
"sha256:1e9fb6f1746500ea91a00193ce2361803c70c6b13f10aae9a33ad7b5bd28e800",
"sha256:2cca17e80ddb151894333377675db90cd0279fa454776e0a4f74308376afd050",
"sha256:30e365e8408759db3778c361f1e4e0fe8e98a875185ae46c795a85e9bafb9cdf",
"sha256:3206bac900e16eda81687d787086f4ffd4f3854980d798e191a9868a6510c3ae",
"sha256:3c23d72058647cee19b30452acc7895621e2de0a0bd5b8a1e34204b9ea9ed43c",
"sha256:407b5f911a83daa285bbf1ef78a9909ee5957f257d3524b8606be37e8643c5f0",
"sha256:4162953714a9212d373ac953c10e3329f1e830d3c7473f2a2e4f25dd6241eef0",
"sha256:5fc7aba72a51b2c80605eba1c50dbf84224dcd206279d30a75c154e5652e1fe4",
"sha256:713ac19307e11de4d9833af0c4bd6778bde0a3d967cafd2f0f347223711c1e31",
"sha256:71b946d80ef3c3f12db157d7778b1fe74a517ca85e94809358b15580983c2ce2",
"sha256:8cc4aed71e20d87e0a6f02094d718a95252f11f8ed143bc112d22167f08d4040",
"sha256:9d41ca62daf36d6b6515ab8765e4c8c4388ee18e2a665701fef2b41563821002",
"sha256:a744e13b000f234cd5a5b2a1f95816b819027c57f385da54ad2b7da1adace2f3",
"sha256:b087ee01396c4b34e9dc41e3a6a0442158206d383c19c7d0396d52067b17c1cb",
"sha256:b0f03af381d33306ce67d18275b61acb4ca111ced645381387a02c8a5ee1b796",
"sha256:b9e4b8dfd587365bdd719ae178fa1b6c1231f81280b1375eef8626dfd8761bf3",
"sha256:c5dd4ec75985b99166c045909e10f0534704d102848b1d9f0992720e908928e7",
"sha256:d2b82f23cd862a9d05108fe99967e9edfa95c136f532a71cb3d28dc252771f50",
"sha256:e58a25764472af07b7e1c4b10b0179c8ea726446c7141076286e41891bf3a563",
"sha256:f3b49107fbfc77333fc2b1ef4d5de2abcd57e7ea3a1482455229494cf2da56ce"
],
"index": "pypi",
"version": "==2.9.0"
},
"ipykernel": {
"hashes": [
"sha256:167c3ef08450f5e060b76c749905acb0e0fbef9365899377a4a1eae728864383",
"sha256:b503913e0b4cce7ed2de965457dfb2edd633e8234161a60e23f2fe2161345d12"
],
"version": "==5.1.2"
},
"ipython": {
"hashes": [
"sha256:c4ab005921641e40a68e405e286e7a1fcc464497e14d81b6914b4fd95e5dee9b",
"sha256:dd76831f065f17bddd7eaa5c781f5ea32de5ef217592cf019e34043b56895aa1"
],
"markers": "python_version >= '3.3'",
"version": "==7.8.0"
},
"ipython-genutils": {
"hashes": [
"sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8",
"sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"
],
"version": "==0.2.0"
},
"ipywidgets": {
"hashes": [
"sha256:13ffeca438e0c0f91ae583dc22f50379b9d6b28390ac7be8b757140e9a771516",
"sha256:e945f6e02854a74994c596d9db83444a1850c01648f1574adf144fbbabe05c97"
],
"version": "==7.5.1"
},
"jedi": {
"hashes": [
"sha256:786b6c3d80e2f06fd77162a07fed81b8baa22dde5d62896a790a331d6ac21a27",
"sha256:ba859c74fa3c966a22f2aeebe1b74ee27e2a462f56d3f5f7ca4a59af61bfe42e"
],
"version": "==0.15.1"
},
"jinja2": {
"hashes": [
"sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013",
"sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b"
],
"version": "==2.10.1"
},
"jsonschema": {
"hashes": [
"sha256:5f9c0a719ca2ce14c5de2fd350a64fd2d13e8539db29836a86adc990bb1a068f",
"sha256:8d4a2b7b6c2237e0199c8ea1a6d3e05bf118e289ae2b9d7ba444182a2959560d"
],
"version": "==3.0.2"
},
"jupyter": {
"hashes": [
"sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7",
"sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78",
"sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f"
],
"index": "pypi",
"version": "==1.0.0"
},
"jupyter-client": {
"hashes": [
"sha256:73a809a2964afa07adcc1521537fddb58c2ffbb7e84d53dc5901cf80480465b3",
"sha256:98e8af5edff5d24e4d31e73bc21043130ae9d955a91aa93fc0bc3b1d0f7b5880"
],
"version": "==5.3.1"
},
"jupyter-console": {
"hashes": [
"sha256:308ce876354924fb6c540b41d5d6d08acfc946984bf0c97777c1ddcb42e0b2f5",
"sha256:cc80a97a5c389cbd30252ffb5ce7cefd4b66bde98219edd16bf5cb6f84bb3568"
],
"version": "==6.0.0"
},
"jupyter-core": {
"hashes": [
"sha256:2c6e7c1e9f2ac45b5c2ceea5730bc9008d92fe59d0725eac57b04c0edfba24f7",
"sha256:f4fa22d6cf25f34807c995f22d2923693575c70f02557bcbfbe59bd5ec8d8b84"
],
"version": "==4.5.0"
},
"kiwisolver": {
"hashes": [
"sha256:05b5b061e09f60f56244adc885c4a7867da25ca387376b02c1efc29cc16bcd0f",
"sha256:26f4fbd6f5e1dabff70a9ba0d2c4bd30761086454aa30dddc5b52764ee4852b7",
"sha256:3b2378ad387f49cbb328205bda569b9f87288d6bc1bf4cd683c34523a2341efe",
"sha256:400599c0fe58d21522cae0e8b22318e09d9729451b17ee61ba8e1e7c0346565c",
"sha256:47b8cb81a7d18dbaf4fed6a61c3cecdb5adec7b4ac292bddb0d016d57e8507d5",
"sha256:53eaed412477c836e1b9522c19858a8557d6e595077830146182225613b11a75",
"sha256:58e626e1f7dfbb620d08d457325a4cdac65d1809680009f46bf41eaf74ad0187",
"sha256:5a52e1b006bfa5be04fe4debbcdd2688432a9af4b207a3f429c74ad625022641",
"sha256:5c7ca4e449ac9f99b3b9d4693debb1d6d237d1542dd6a56b3305fe8a9620f883",
"sha256:682e54f0ce8f45981878756d7203fd01e188cc6c8b2c5e2cf03675390b4534d5",
"sha256:79bfb2f0bd7cbf9ea256612c9523367e5ec51d7cd616ae20ca2c90f575d839a2",
"sha256:7f4dd50874177d2bb060d74769210f3bce1af87a8c7cf5b37d032ebf94f0aca3",
"sha256:8944a16020c07b682df861207b7e0efcd2f46c7488619cb55f65882279119389",
"sha256:8aa7009437640beb2768bfd06da049bad0df85f47ff18426261acecd1cf00897",
"sha256:939f36f21a8c571686eb491acfffa9c7f1ac345087281b412d63ea39ca14ec4a",
"sha256:9733b7f64bd9f807832d673355f79703f81f0b3e52bfce420fc00d8cb28c6a6c",
"sha256:a02f6c3e229d0b7220bd74600e9351e18bc0c361b05f29adae0d10599ae0e326",
"sha256:a0c0a9f06872330d0dd31b45607197caab3c22777600e88031bfe66799e70bb0",
"sha256:acc4df99308111585121db217681f1ce0eecb48d3a828a2f9bbf9773f4937e9e",
"sha256:b64916959e4ae0ac78af7c3e8cef4becee0c0e9694ad477b4c6b3a536de6a544",
"sha256:d3fcf0819dc3fea58be1fd1ca390851bdb719a549850e708ed858503ff25d995",
"sha256:d52e3b1868a4e8fd18b5cb15055c76820df514e26aa84cc02f593d99fef6707f",
"sha256:db1a5d3cc4ae943d674718d6c47d2d82488ddd94b93b9e12d24aabdbfe48caee",
"sha256:e3a21a720791712ed721c7b95d433e036134de6f18c77dbe96119eaf7aa08004",
"sha256:e8bf074363ce2babeb4764d94f8e65efd22e6a7c74860a4f05a6947afc020ff2",
"sha256:f16814a4a96dc04bf1da7d53ee8d5b1d6decfc1a92a63349bb15d37b6a263dd9",
"sha256:f2b22153870ca5cf2ab9c940d7bc38e8e9089fa0f7e5856ea195e1cf4ff43d5a",
"sha256:f790f8b3dff3d53453de6a7b7ddd173d2e020fb160baff578d578065b108a05f"
],
"version": "==1.1.0"
},
"markupsafe": {
"hashes": [
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
],
"version": "==1.1.1"
},
"matplotlib": {
"hashes": [
"sha256:1febd22afe1489b13c6749ea059d392c03261b2950d1d45c17e3aed812080c93",
"sha256:31a30d03f39528c79f3a592857be62a08595dec4ac034978ecd0f814fa0eec2d",
"sha256:4442ce720907f67a79d45de9ada47be81ce17e6c2f448b3c64765af93f6829c9",
"sha256:796edbd1182cbffa7e1e7a97f1e141f875a8501ba8dd834269ae3cd45a8c976f",
"sha256:934e6243df7165aad097572abf5b6003c77c9b6c480c3c4de6f2ef1b5fdd4ec0",
"sha256:bab9d848dbf1517bc58d1f486772e99919b19efef5dd8596d4b26f9f5ee08b6b",
"sha256:c1fe1e6cdaa53f11f088b7470c2056c0df7d80ee4858dadf6cbe433fcba4323b",
"sha256:e5b8aeca9276a3a988caebe9f08366ed519fff98f77c6df5b64d7603d0e42e36",
"sha256:ec6bd0a6a58df3628ff269978f4a4b924a0d371ad8ce1f8e2b635b99e482877a"
],
"index": "pypi",
"version": "==3.1.1"
},
"mistune": {
"hashes": [
"sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e",
"sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"
],
"version": "==0.8.4"
},
"nbconvert": {
"hashes": [
"sha256:427a468ec26e7d68a529b95f578d5cbf018cb4c1f889e897681c2b6d11897695",
"sha256:48d3c342057a2cf21e8df820d49ff27ab9f25fc72b8f15606bd47967333b2709"
],
"version": "==5.6.0"
},
"nbformat": {
"hashes": [
"sha256:b9a0dbdbd45bb034f4f8893cafd6f652ea08c8c1674ba83f2dc55d3955743b0b",
"sha256:f7494ef0df60766b7cabe0a3651556345a963b74dbc16bc7c18479041170d402"
],
"version": "==4.4.0"
},
"notebook": {
"hashes": [
"sha256:660976fe4fe45c7aa55e04bf4bccb9f9566749ff637e9020af3422f9921f9a5d",
"sha256:b0a290f5cc7792d50a21bec62b3c221dd820bf00efa916ce9aeec4b5354bde20"
],
"version": "==6.0.1"
},
"numpy": {
"hashes": [
"sha256:03f2ebcbffcce2dec8860633b89a93e80c6a239d21a77ae8b241450dc21e8c35",
"sha256:078c8025da5ab9e8657edc9c2a1e9642e06e953bc7baa2e65c1aa9d9dfb7e98b",
"sha256:0fbfa98c5d5c3c6489cc1e852ec94395d51f35d9ebe70c6850e47f465038cdf4",
"sha256:1c841033f4fe6801648180c3033c45b3235a8bbd09bc7249010f99ea27bb6790",
"sha256:2c0984a01ddd0aeec89f0ce46ef21d64761048cd76c0074d0658c91f9131f154",
"sha256:4c166dcb0fff7cb3c0bbc682dfb5061852a2547efb6222e043a7932828c08fb5",
"sha256:8c2d98d0623bd63fb883b65256c00454d5f53127a5a7bcdaa8bdc582814e8cb4",
"sha256:8cb4b6ae45aad6d26712a1ce0a3f2556c5e1484867f9649e03496e45d6a5eba4",
"sha256:93050e73c446c82065b7410221b07682e475ac51887cd9368227a5d944afae80",
"sha256:a3f6b3024f8826d8b1490e6e2a9b99e841cd2c375791b1df62991bd8f4c00b89",
"sha256:bede70fd8699695363f39e86c1e869b2c8b74fb5ef135a67b9e1eeebff50322a",
"sha256:c304b2221f33489cd15a915237a84cdfe9420d7e4d4828c78a0820f9d990395c",
"sha256:f11331530f0eff69a758d62c2461cd98cdc2eae0147279d8fc86e0464eb7e8ca",
"sha256:fa5f2a8ef1e07ba258dc07d4dd246de23ef4ab920ae0f3fa2a1cc5e90f0f1888",
"sha256:fb6178b0488b0ce6a54bc4accbdf5225e937383586555604155d64773f6beb2b",
"sha256:fd5e830d4dc31658d61a6452cd3e842213594d8c15578cdae6829e36ad9c0930"
],
"index": "pypi",
"version": "==1.17.1"
},
"pandocfilters": {
"hashes": [
"sha256:b3dd70e169bb5449e6bc6ff96aea89c5eea8c5f6ab5e207fc2f521a2cf4a0da9"
],
"version": "==1.4.2"
},
"parso": {
"hashes": [
"sha256:63854233e1fadb5da97f2744b6b24346d2750b85965e7e399bec1620232797dc",
"sha256:666b0ee4a7a1220f65d367617f2cd3ffddff3e205f3f16a0284df30e774c2a9c"
],
"version": "==0.5.1"
},
"pexpect": {
"hashes": [
"sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1",
"sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb"
],
"markers": "sys_platform != 'win32'",
"version": "==4.7.0"
},
"pickleshare": {
"hashes": [
"sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca",
"sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"
],
"version": "==0.7.5"
},
"prometheus-client": {
"hashes": [
"sha256:71cd24a2b3eb335cb800c7159f423df1bd4dcd5171b234be15e3f31ec9f622da"
],
"version": "==0.7.1"
},
"prompt-toolkit": {
"hashes": [
"sha256:11adf3389a996a6d45cc277580d0d53e8a5afd281d0c9ec71b28e6f121463780",
"sha256:2519ad1d8038fd5fc8e770362237ad0364d16a7650fb5724af6997ed5515e3c1",
"sha256:977c6583ae813a37dc1c2e1b715892461fcbdaa57f6fc62f33a528c4886c8f55"
],
"version": "==2.0.9"
},
"ptyprocess": {
"hashes": [
"sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0",
"sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f"
],
"markers": "os_name != 'nt'",
"version": "==0.6.0"
},
"pygments": {
"hashes": [
"sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
"sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
],
"version": "==2.4.2"
},
"pyparsing": {
"hashes": [
"sha256:6f98a7b9397e206d78cc01df10131398f1c8b8510a2f4d97d9abd82e1aacdd80",
"sha256:d9338df12903bbf5d65a0e4e87c2161968b10d2e489652bb47001d82a9b028b4"
],
"version": "==2.4.2"
},
"pyrsistent": {
"hashes": [
"sha256:34b47fa169d6006b32e99d4b3c4031f155e6e68ebcc107d6454852e8e0ee6533"
],
"version": "==0.15.4"
},
"python-dateutil": {
"hashes": [
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
],
"version": "==2.8.0"
},
"pyzmq": {
"hashes": [
"sha256:01636e95a88d60118479041c6aaaaf5419c6485b7b1d37c9c4dd424b7b9f1121",
"sha256:021dba0d1436516092c624359e5da51472b11ba8edffa334218912f7e8b65467",
"sha256:0463bd941b6aead494d4035f7eebd70035293dd6caf8425993e85ad41de13fa3",
"sha256:05fd51edd81eed798fccafdd49c936b6c166ffae7b32482e4d6d6a2e196af4e6",
"sha256:1fadc8fbdf3d22753c36d4172169d184ee6654f8d6539e7af25029643363c490",
"sha256:22efa0596cf245a78a99060fe5682c4cd00c58bb7614271129215c889062db80",
"sha256:260c70b7c018905ec3659d0f04db735ac830fe27236e43b9dc0532cf7c9873ef",
"sha256:2762c45e289732d4450406cedca35a9d4d71e449131ba2f491e0bf473e3d2ff2",
"sha256:2fc6cada8dc53521c1189596f1898d45c5f68603194d3a6453d6db4b27f4e12e",
"sha256:343b9710a61f2b167673bea1974e70b5dccfe64b5ed10626798f08c1f7227e72",
"sha256:41bf96d5f554598a0632c3ec28e3026f1d6591a50f580df38eff0b8067efb9e7",
"sha256:856b2cdf7a1e2cbb84928e1e8db0ea4018709b39804103d3a409e5584f553f57",
"sha256:85b869abc894672de9aecdf032158ea8ad01e2f0c3b09ef60e3687fb79418096",
"sha256:93f44739db69234c013a16990e43db1aa0af3cf5a4b8b377d028ff24515fbeb3",
"sha256:98fa3e75ccb22c0dc99654e3dd9ff693b956861459e8c8e8734dd6247b89eb29",
"sha256:9a22c94d2e93af8bebd4fcf5fa38830f5e3b1ff0d4424e2912b07651eb1bafb4",
"sha256:a7d3f4b4bbb5d7866ae727763268b5c15797cbd7b63ea17f3b0ec1067da8994b",
"sha256:b645a49376547b3816433a7e2d2a99135c8e651e50497e7ecac3bd126e4bea16",
"sha256:cf0765822e78cf9e45451647a346d443f66792aba906bc340f4e0ac7870c169c",
"sha256:dc398e1e047efb18bfab7a8989346c6921a847feae2cad69fedf6ca12fb99e2c",
"sha256:dd5995ae2e80044e33b5077fb4bc2b0c1788ac6feaf15a6b87a00c14b4bdd682",
"sha256:e03fe5e07e70f245dc9013a9d48ae8cc4b10c33a1968039c5a3b64b5d01d083d",
"sha256:ea09a306144dff2795e48439883349819bef2c53c0ee62a3c2fae429451843bb",
"sha256:f4e37f33da282c3c319849877e34f97f0a3acec09622ec61b7333205bdd13b52",
"sha256:fa4bad0d1d173dee3e8ef3c3eb6b2bb6c723fc7a661eeecc1ecb2fa99860dd45"
],
"version": "==18.1.0"
},
"qtconsole": {
"hashes": [
"sha256:40d5d8e00d070ea266dbf6f0da74c4b9597b8b8d67cd8233c3ffd8debf923703",
"sha256:b91e7412587e6cfe1644696538f73baf5611e837be5406633218443b2827c6d9"
],
"version": "==4.5.5"
},
"scipy": {
"hashes": [
"sha256:0baa64bf42592032f6f6445a07144e355ca876b177f47ad8d0612901c9375bef",
"sha256:243b04730d7223d2b844bda9500310eecc9eda0cba9ceaf0cde1839f8287dfa8",
"sha256:2643cfb46d97b7797d1dbdb6f3c23fe3402904e3c90e6facfe6a9b98d808c1b5",
"sha256:396eb4cdad421f846a1498299474f0a3752921229388f91f60dc3eda55a00488",
"sha256:3ae3692616975d3c10aca6d574d6b4ff95568768d4525f76222fb60f142075b9",
"sha256:435d19f80b4dcf67dc090cc04fde2c5c8a70b3372e64f6a9c58c5b806abfa5a8",
"sha256:46a5e55850cfe02332998b3aef481d33f1efee1960fe6cfee0202c7dd6fc21ab",
"sha256:75b513c462e58eeca82b22fc00f0d1875a37b12913eee9d979233349fce5c8b2",
"sha256:7ccfa44a08226825126c4ef0027aa46a38c928a10f0a8a8483c80dd9f9a0ad44",
"sha256:89dd6a6d329e3f693d1204d5562dd63af0fd7a17854ced17f9cbc37d5b853c8d",
"sha256:a81da2fe32f4eab8b60d56ad43e44d93d392da228a77e229e59b51508a00299c",
"sha256:a9d606d11eb2eec7ef893eb825017fbb6eef1e1d0b98a5b7fc11446ebeb2b9b1",
"sha256:ac37eb652248e2d7cbbfd89619dce5ecfd27d657e714ed049d82f19b162e8d45",
"sha256:cbc0611699e420774e945f6a4e2830f7ca2b3ee3483fca1aa659100049487dd5",
"sha256:d02d813ec9958ed63b390ded463163685af6025cb2e9a226ec2c477df90c6957",
"sha256:dd3b52e00f93fd1c86f2d78243dfb0d02743c94dd1d34ffea10055438e63b99d"
],
"index": "pypi",
"version": "==1.3.1"
},
"send2trash": {
"hashes": [
"sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2",
"sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b"
],
"version": "==1.5.0"
},
"six": {
"hashes": [
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
],
"version": "==1.12.0"
},
"terminado": {
"hashes": [
"sha256:d9d012de63acb8223ac969c17c3043337c2fcfd28f3aea1ee429b345d01ef460",
"sha256:de08e141f83c3a0798b050ecb097ab6259c3f0331b2f7b7750c9075ced2c20c2"
],
"version": "==0.8.2"
},
"testpath": {
"hashes": [
"sha256:46c89ebb683f473ffe2aab0ed9f12581d4d078308a3cb3765d79c6b2317b0109",
"sha256:b694b3d9288dbd81685c5d2e7140b81365d46c29f5db4bc659de5aa6b98780f8"
],
"version": "==0.4.2"
},
"tornado": {
"hashes": [
"sha256:349884248c36801afa19e342a77cc4458caca694b0eda633f5878e458a44cb2c",
"sha256:398e0d35e086ba38a0427c3b37f4337327231942e731edaa6e9fd1865bbd6f60",
"sha256:4e73ef678b1a859f0cb29e1d895526a20ea64b5ffd510a2307b5998c7df24281",
"sha256:559bce3d31484b665259f50cd94c5c28b961b09315ccd838f284687245f416e5",
"sha256:abbe53a39734ef4aba061fca54e30c6b4639d3e1f59653f0da37a0003de148c7",
"sha256:c845db36ba616912074c5b1ee897f8e0124df269468f25e4fe21fe72f6edd7a9",
"sha256:c9399267c926a4e7c418baa5cbe91c7d1cf362d505a1ef898fde44a07c9dd8a5"
],
"version": "==6.0.3"
},
"traitlets": {
"hashes": [
"sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835",
"sha256:c6cb5e6f57c5a9bdaa40fa71ce7b4af30298fbab9ece9815b5d995ab6217c7d9"
],
"version": "==4.3.2"
},
"wcwidth": {
"hashes": [
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
],
"version": "==0.1.7"
},
"webencodings": {
"hashes": [
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
"sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
],
"version": "==0.5.1"
},
"widgetsnbextension": {
"hashes": [
"sha256:079f87d87270bce047512400efd70238820751a11d2d8cb137a5a5bdbaf255c7",
"sha256:bd314f8ceb488571a5ffea6cc5b9fc6cba0adaf88a9d2386b93a489751938bcd"
],
"version": "==3.5.1"
}
},
"develop": {}
}

10
README.markdown

@ -0,0 +1,10 @@
# psas-magnetometer-calibration
Example of how to do soft and hard iron calibration from a 3DOF magnetometer.
### Install and run locally:
$ pipenv install
$ pipenv run jupyter notebook
And edit the notebook.

3
README.md

@ -1,3 +0,0 @@
# psas-magnetometer-calibration
Example of how to do soft and hard iron calibration from a 3DOF magnetometer.

BIN
data/L-12_calibration.hdf5

7
figures.tpl

@ -0,0 +1,7 @@
{% extends 'markdown.tpl'%}
{% block data_png %}
<figure class="{{ cell.metadata['class'] }}">
<img src="{{ output.metadata.filenames['image/png'] | path2url }}">
</figure>
{% endblock data_png %}

510
matplotlibrc

@ -0,0 +1,510 @@
### MATPLOTLIBRC FORMAT
# This is a sample matplotlib configuration file - you can find a copy
# of it on your system in
# site-packages/matplotlib/mpl-data/matplotlibrc. If you edit it
# there, please note that it will be overwritten in your next install.
# If you want to keep a permanent local copy that will not be
# overwritten, place it in the following location:
# unix/linux:
# $HOME/.config/matplotlib/matplotlibrc or
# $XDG_CONFIG_HOME/matplotlib/matplotlibrc (if $XDG_CONFIG_HOME is set)
# other platforms:
# $HOME/.matplotlib/matplotlibrc
#
# See http://matplotlib.org/users/customizing.html#the-matplotlibrc-file for
# more details on the paths which are checked for the configuration file.
#
# This file is best viewed in a editor which supports python mode
# syntax highlighting. Blank lines, or lines starting with a comment
# symbol, are ignored, as are trailing comments. Other lines must
# have the format
# key : val # optional comment
#
# Colors: for the color values below, you can either use - a
# matplotlib color string, such as r, k, or b - an rgb tuple, such as
# (1.0, 0.5, 0.0) - a hex string, such as ff00ff or #ff00ff - a scalar
# grayscale intensity such as 0.75 - a legal html color name, e.g., red,
# blue, darkslategray
#### CONFIGURATION BEGINS HERE
# The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
# CocoaAgg MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
# Template.
# You can also deploy your own backend outside of matplotlib by
# referring to the module name (which must be in the PYTHONPATH) as
# 'module://my_backend'.
#backend : qt4agg
# If you are using the Qt4Agg backend, you can choose here
# to use the PyQt4 bindings or the newer PySide bindings to
# the underlying Qt4 toolkit.
#backend.qt4 : PyQt4 # PyQt4 | PySide
# Note that this can be overridden by the environment variable
# QT_API used by Enthought Tool Suite (ETS); valid values are
# "pyqt" and "pyside". The "pyqt" setting has the side effect of
# forcing the use of Version 2 API for QString and QVariant.
# The port to use for the web server in the WebAgg backend.
# webagg.port : 8888
# If webagg.port is unavailable, a number of other random ports will
# be tried until one that is available is found.
# webagg.port_retries : 50
# When True, open the webbrowser to the plot that is shown
# webagg.open_in_browser : True
# When True, the figures rendered in the nbagg backend are created with
# a transparent background.
# nbagg.transparent : True
# if you are running pyplot inside a GUI and your backend choice
# conflicts, we will automatically try to find a compatible one for
# you if backend_fallback is True
#backend_fallback: True
#interactive : False
#toolbar : toolbar2 # None | toolbar2 ("classic" is deprecated)
#timezone : UTC # a pytz timezone string, e.g., US/Central or Europe/Paris
# Where your matplotlib data lives if you installed to a non-default
# location. This is where the matplotlib fonts, bitmaps, etc reside
#datapath : /home/jdhunter/mpldata
### LINES
# See http://matplotlib.org/api/artist_api.html#module-matplotlib.lines for more
# information on line properties.
lines.linewidth : 1.7 # line width in points
#lines.linestyle : - # solid line
#lines.color : blue # has no affect on plot(); see axes.prop_cycle
#lines.marker : None # the default marker
#lines.markeredgewidth : 0.5 # the line width around the marker symbol
#lines.markersize : 6 # markersize, in points
#lines.dash_joinstyle : miter # miter|round|bevel
#lines.dash_capstyle : butt # butt|round|projecting
#lines.solid_joinstyle : miter # miter|round|bevel
#lines.solid_capstyle : projecting # butt|round|projecting
#lines.antialiased : True # render lines in antialised (no jaggies)
#markers.fillstyle: full # full|left|right|bottom|top|none
### PATCHES
# Patches are graphical objects that fill 2D space, like polygons or
# circles. See
# http://matplotlib.org/api/artist_api.html#module-matplotlib.patches
# information on patch properties
patch.linewidth : 0.1 # edge width in points
#patch.facecolor : blue
#patch.edgecolor : black
#patch.antialiased : True # render patches in antialised (no jaggies)
### FONT
#
# font properties used by text.Text. See
# http://matplotlib.org/api/font_manager_api.html for more
# information on font properties. The 6 font properties used for font
# matching are given below with their default values.
#
# The font.family property has five values: 'serif' (e.g., Times),
# 'sans-serif' (e.g., Helvetica), 'cursive' (e.g., Zapf-Chancery),
# 'fantasy' (e.g., Western), and 'monospace' (e.g., Courier). Each of
# these font families has a default list of font names in decreasing
# order of priority associated with them. When text.usetex is False,
# font.family may also be one or more concrete font names.
#
# The font.style property has three values: normal (or roman), italic
# or oblique. The oblique style will be used for italic, if it is not
# present.
#
# The font.variant property has two values: normal or small-caps. For
# TrueType fonts, which are scalable fonts, small-caps is equivalent
# to using a font size of 'smaller', or about 83% of the current font
# size.
#
# The font.weight property has effectively 13 values: normal, bold,
# bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as
# 400, and bold is 700. bolder and lighter are relative values with
# respect to the current weight.
#
# The font.stretch property has 11 values: ultra-condensed,
# extra-condensed, condensed, semi-condensed, normal, semi-expanded,
# expanded, extra-expanded, ultra-expanded, wider, and narrower. This
# property is not currently implemented.
#
# The font.size property is the default font size for text, given in pts.
# 12pt is the standard value.
#
#font.family : sans-serif
#font.style : normal
#font.variant : normal
#font.weight : medium
#font.stretch : normal
# note that font.size controls default text sizes. To configure
# special text sizes tick labels, axes, labels, title, etc, see the rc
# settings for axes and ticks. Special text sizes can be defined
# relative to font.size, using the following values: xx-small, x-small,
# small, medium, large, x-large, xx-large, larger, or smaller
#font.size : 24.0
#font.serif : Bitstream Vera Serif, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
#font.sans-serif : Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
#font.cursive : Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, cursive
#font.fantasy : Comic Sans MS, Chicago, Charcoal, Impact, Western, Humor Sans, fantasy
#font.monospace : Bitstream Vera Sans Mono, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace
### TEXT
# text properties used by text.Text. See
# http://matplotlib.org/api/artist_api.html#module-matplotlib.text for more
# information on text properties
#text.color : black
### LaTeX customizations. See http://wiki.scipy.org/Cookbook/Matplotlib/UsingTex
#text.usetex : False # use latex for all text handling. The following fonts
# are supported through the usual rc parameter settings:
# new century schoolbook, bookman, times, palatino,
# zapf chancery, charter, serif, sans-serif, helvetica,
# avant garde, courier, monospace, computer modern roman,
# computer modern sans serif, computer modern typewriter
# If another font is desired which can loaded using the
# LaTeX \usepackage command, please inquire at the
# matplotlib mailing list
#text.latex.unicode : False # use "ucs" and "inputenc" LaTeX packages for handling
# unicode strings.
#text.latex.preamble : # IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES
# AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP
# IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO.
# preamble is a comma separated list of LaTeX statements
# that are included in the LaTeX document preamble.
# An example:
# text.latex.preamble : \usepackage{bm},\usepackage{euler}
# The following packages are always loaded with usetex, so
# beware of package collisions: color, geometry, graphicx,
# type1cm, textcomp. Adobe Postscript (PSSNFS) font packages
# may also be loaded, depending on your font settings
#text.dvipnghack : None # some versions of dvipng don't handle alpha
# channel properly. Use True to correct
# and flush ~/.matplotlib/tex.cache
# before testing and False to force
# correction off. None will try and
# guess based on your dvipng version
#text.hinting : auto # May be one of the following:
# 'none': Perform no hinting
# 'auto': Use freetype's autohinter
# 'native': Use the hinting information in the
# font file, if available, and if your
# freetype library supports it
# 'either': Use the native hinting information,
# or the autohinter if none is available.
# For backward compatibility, this value may also be
# True === 'auto' or False === 'none'.
#text.hinting_factor : 8 # Specifies the amount of softness for hinting in the
# horizontal direction. A value of 1 will hint to full
# pixels. A value of 2 will hint to half pixels etc.
#text.antialiased : True # If True (default), the text will be antialiased.
# This only affects the Agg backend.
# The following settings allow you to select the fonts in math mode.
# They map from a TeX font name to a fontconfig font pattern.
# These settings are only used if mathtext.fontset is 'custom'.
# Note that this "custom" mode is unsupported and may go away in the
# future.
#mathtext.cal : cursive
#mathtext.rm : serif
#mathtext.tt : monospace
#mathtext.it : serif:italic
#mathtext.bf : serif:bold
#mathtext.sf : sans
#mathtext.fontset : cm # Should be 'cm' (Computer Modern), 'stix',
# 'stixsans' or 'custom'
#mathtext.fallback_to_cm : True # When True, use symbols from the Computer Modern
# fonts when a symbol can not be found in one of
# the custom math fonts.
#mathtext.default : it # The default font to use for math.
# Can be any of the LaTeX font names, including
# the special name "regular" for the same font
# used in regular text.
### AXES
# default face and edge color, default tick sizes,
# default fontsizes for ticklabels, and so on. See
# http://matplotlib.org/api/axes_api.html#module-matplotlib.axes
#axes.hold : True # whether to clear the axes by default on
#axes.facecolor : white # axes background color
axes.edgecolor : 666666 # axes edge color
#axes.linewidth : 1.0 # edge linewidth
axes.grid : True # display grid or not
axes.titlesize : xx-large # fontsize of the axes title
axes.labelsize : large # fontsize of the x any y labels
#axes.labelpad : 5.0 # space between label and axis
#axes.labelweight : normal # weight of the x and y labels
axes.labelcolor : 444444
#axes.axisbelow : False # whether axis gridlines and ticks are below
# the axes elements (lines, text, etc)
#axes.formatter.limits : -7, 7 # use scientific notation if log10
# of the axis range is smaller than the
# first or larger than the second
#axes.formatter.use_locale : False # When True, format tick labels
# according to the user's locale.
# For example, use ',' as a decimal
# separator in the fr_FR locale.
#axes.formatter.use_mathtext : False # When True, use mathtext for scientific
# notation.
#axes.formatter.useoffset : True # If True, the tick label formatter
# will default to labeling ticks relative
# to an offset when the data range is very
# small compared to the minimum absolute
# value of the data.
#axes.unicode_minus : True # use unicode for the minus symbol
# rather than hyphen. See
# http://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes
axes.prop_cycle : cycler('color', ['e31d1d', '709afa', '76e146', 'c', 'm', 'y', 'k'])
# color cycle for plot lines
# as list of string colorspecs:
# single letter, long name, or
# web-style hex
#axes.xmargin : 0 # x margin. See `axes.Axes.margins`
#axes.ymargin : 0 # y margin See `axes.Axes.margins`
#polaraxes.grid : True # display grid on polar axes
#axes3d.grid : True # display grid on 3d axes
### TICKS
# see http://matplotlib.org/api/axis_api.html#matplotlib.axis.Tick
#xtick.major.size : 4 # major tick size in points
#xtick.minor.size : 2 # minor tick size in points
#xtick.major.width : 0.5 # major tick width in points
#xtick.minor.width : 0.5 # minor tick width in points
#xtick.major.pad : 4 # distance to major tick label in points
#xtick.minor.pad : 4 # distance to the minor tick label in points
#xtick.color : k # color of the tick labels
#xtick.labelsize : medium # fontsize of the tick labels
#xtick.direction : in # direction: in, out, or inout
#ytick.major.size : 4 # major tick size in points
#ytick.minor.size : 2 # minor tick size in points
#ytick.major.width : 0.5 # major tick width in points
#ytick.minor.width : 0.5 # minor tick width in points
#ytick.major.pad : 4 # distance to major tick label in points
#ytick.minor.pad : 4 # distance to the minor tick label in points
#ytick.color : k # color of the tick labels
#ytick.labelsize : medium # fontsize of the tick labels
#ytick.direction : in # direction: in, out, or inout
### GRIDS
#grid.color : black # grid color
#grid.linestyle : : # dotted
#grid.linewidth : 0.5 # in points
grid.alpha : 0.4 # transparency, between 0.0 and 1.0
### Legend
#legend.fancybox : False # if True, use a rounded box for the
# legend, else a rectangle
#legend.isaxes : True
#legend.numpoints : 2 # the number of points in the legend line
#legend.fontsize : large
#legend.borderpad : 0.5 # border whitespace in fontsize units
#legend.markerscale : 1.0 # the relative size of legend markers vs. original
# the following dimensions are in axes coords
#legend.labelspacing : 0.5 # the vertical space between the legend entries in fraction of fontsize
#legend.handlelength : 2. # the length of the legend lines in fraction of fontsize
#legend.handleheight : 0.7 # the height of the legend handle in fraction of fontsize
#legend.handletextpad : 0.8 # the space between the legend line and legend text in fraction of fontsize
#legend.borderaxespad : 0.5 # the border between the axes and legend edge in fraction of fontsize
#legend.columnspacing : 2. # the border between the axes and legend edge in fraction of fontsize
#legend.shadow : False
#legend.frameon : True # whether or not to draw a frame around legend
#legend.framealpha : None # opacity of of legend frame
#legend.scatterpoints : 3 # number of scatter points
### FIGURE
# See http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure
#figure.titlesize : medium # size of the figure title
#figure.titleweight : normal # weight of the figure title
#figure.figsize : 8, 6 # figure size in inches
#figure.dpi : 80 # figure dots per inch
#figure.facecolor : 0.75 # figure facecolor; 0.75 is scalar gray
#figure.edgecolor : white # figure edgecolor
#figure.autolayout : False # When True, automatically adjust subplot
# parameters to make the plot fit the figure
#figure.max_open_warning : 20 # The maximum number of figures to open through
# the pyplot interface before emitting a warning.
# If less than one this feature is disabled.
# The figure subplot parameters. All dimensions are a fraction of the
# figure width or height
#figure.subplot.left : 0.125 # the left side of the subplots of the figure
#figure.subplot.right : 0.9 # the right side of the subplots of the figure
#figure.subplot.bottom : 0.1 # the bottom of the subplots of the figure
#figure.subplot.top : 0.9 # the top of the subplots of the figure
#figure.subplot.wspace : 0.2 # the amount of width reserved for blank space between subplots
#figure.subplot.hspace : 0.2 # the amount of height reserved for white space between subplots
### IMAGES
#image.aspect : equal # equal | auto | a number
#image.interpolation : bilinear # see help(imshow) for options
#image.cmap : jet # gray | jet etc...
#image.lut : 256 # the size of the colormap lookup table
#image.origin : upper # lower | upper
#image.resample : False
#image.composite_image : True # When True, all the images on a set of axes are
# combined into a single composite image before
# saving a figure as a vector graphics file,
# such as a PDF.
### CONTOUR PLOTS
#contour.negative_linestyle : dashed # dashed | solid
#contour.corner_mask : True # True | False | legacy
### ERRORBAR PLOTS
#errorbar.capsize : 3 # length of end cap on error bars in pixels
### Agg rendering
### Warning: experimental, 2008/10/10
#agg.path.chunksize : 0 # 0 to disable; values in the range
# 10000 to 100000 can improve speed slightly
# and prevent an Agg rendering failure
# when plotting very large data sets,
# especially if they are very gappy.
# It may cause minor artifacts, though.
# A value of 20000 is probably a good
# starting point.
### SAVING FIGURES
#path.simplify : True # When True, simplify paths by removing "invisible"
# points to reduce file size and increase rendering
# speed
#path.simplify_threshold : 0.1 # The threshold of similarity below which
# vertices will be removed in the simplification
# process
#path.snap : True # When True, rectilinear axis-aligned paths will be snapped to
# the nearest pixel when certain criteria are met. When False,
# paths will never be snapped.
#path.sketch : None # May be none, or a 3-tuple of the form (scale, length,
# randomness).
# *scale* is the amplitude of the wiggle
# perpendicular to the line (in pixels). *length*
# is the length of the wiggle along the line (in
# pixels). *randomness* is the factor by which
# the length is randomly scaled.
# the default savefig params can be different from the display params
# e.g., you may want a higher resolution, or to make the figure
# background white
#savefig.dpi : 100 # figure dots per inch
#savefig.facecolor : white # figure facecolor when saving
#savefig.edgecolor : white # figure edgecolor when saving
#savefig.format : png # png, ps, pdf, svg
#savefig.bbox : standard # 'tight' or 'standard'.
# 'tight' is incompatible with pipe-based animation
# backends but will workd with temporary file based ones:
# e.g. setting animation.writer to ffmpeg will not work,
# use ffmpeg_file instead
#savefig.pad_inches : 0.1 # Padding to be used when bbox is set to 'tight'
#savefig.jpeg_quality: 95 # when a jpeg is saved, the default quality parameter.
#savefig.directory : ~ # default directory in savefig dialog box,
# leave empty to always use current working directory
#savefig.transparent : False # setting that controls whether figures are saved with a
# transparent background by default
# tk backend params
#tk.window_focus : False # Maintain shell focus for TkAgg
# ps backend params
#ps.papersize : letter # auto, letter, legal, ledger, A0-A10, B0-B10
#ps.useafm : False # use of afm fonts, results in small files
#ps.usedistiller : False # can be: None, ghostscript or xpdf
# Experimental: may produce smaller files.
# xpdf intended for production of publication quality files,
# but requires ghostscript, xpdf and ps2eps
#ps.distiller.res : 6000 # dpi
#ps.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType)
# pdf backend params
#pdf.compression : 6 # integer from 0 to 9
# 0 disables compression (good for debugging)
#pdf.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType)
# svg backend params
#svg.image_inline : True # write raster image data directly into the svg file
#svg.image_noscale : False # suppress scaling of raster data embedded in SVG
#svg.fonttype : 'path' # How to handle SVG fonts:
# 'none': Assume fonts are installed on the machine where the SVG will be viewed.
# 'path': Embed characters as paths -- supported by most SVG renderers
# 'svgfont': Embed characters as SVG fonts -- supported only by Chrome,
# Opera and Safari
# docstring params
#docstring.hardcopy = False # set this when you want to generate hardcopy docstring
# Set the verbose flags. This controls how much information
# matplotlib gives you at runtime and where it goes. The verbosity
# levels are: silent, helpful, debug, debug-annoying. Any level is
# inclusive of all the levels below it. If your setting is "debug",
# you'll get all the debug and helpful messages. When submitting
# problems to the mailing-list, please set verbose to "helpful" or "debug"
# and paste the output into your report.
#
# The "fileo" gives the destination for any calls to verbose.report.
# These objects can a filename, or a filehandle like sys.stdout.
#
# You can override the rc default verbosity from the command line by
# giving the flags --verbose-LEVEL where LEVEL is one of the legal
# levels, e.g., --verbose-helpful.
#
# You can access the verbose instance in your code
# from matplotlib import verbose.
#verbose.level : silent # one of silent, helpful, debug, debug-annoying
#verbose.fileo : sys.stdout # a log filename, sys.stdout or sys.stderr
# Event keys to interact with figures/plots via keyboard.
# Customize these settings according to your needs.
# Leave the field(s) empty if you don't need a key-map. (i.e., fullscreen : '')
#keymap.fullscreen : f # toggling
#keymap.home : h, r, home # home or reset mnemonic
#keymap.back : left, c, backspace # forward / backward keys to enable
#keymap.forward : right, v # left handed quick navigation
#keymap.pan : p # pan mnemonic
#keymap.zoom : o # zoom mnemonic
#keymap.save : s # saving current figure
#keymap.quit : ctrl+w, cmd+w # close the current figure
#keymap.grid : g # switching on/off a grid in current axes
#keymap.yscale : l # toggle scaling of y-axes ('log'/'linear')
#keymap.xscale : L, k # toggle scaling of x-axes ('log'/'linear')
#keymap.all_axes : a # enable all axes
# Control location of examples data files
#examples.directory : '' # directory to look in for custom installation
###ANIMATION settings
#animation.html : 'none' # How to display the animation as HTML in
# the IPython notebook. 'html5' uses
# HTML5 video tag.
#animation.writer : ffmpeg # MovieWriter 'backend' to use
#animation.codec : mpeg4 # Codec to use for writing movie
#animation.bitrate: -1 # Controls size/quality tradeoff for movie.
# -1 implies let utility auto-determine
#animation.frame_format: 'png' # Controls frame format used by temp files
#animation.ffmpeg_path: 'ffmpeg' # Path to ffmpeg binary. Without full path
# $PATH is searched
#animation.ffmpeg_args: '' # Additional arguments to pass to ffmpeg
#animation.avconv_path: 'avconv' # Path to avconv binary. Without full path
# $PATH is searched
#animation.avconv_args: '' # Additional arguments to pass to avconv
#animation.mencoder_path: 'mencoder'
# Path to mencoder binary. Without full path
# $PATH is searched
#animation.mencoder_args: '' # Additional arguments to pass to mencoder
#animation.convert_path: 'convert' # Path to ImageMagick's convert binary.
# On Windows use the full path since convert
# is also the name of a system tool.

430
post.ipynb

@ -0,0 +1,430 @@
{
"cells": [
{
"cell_type": "raw",
"metadata": {},
"source": [
"---\n",
"title: PSAS Magnetometer Calibration\n",
"author: Nathan\n",
"date: 2019/9/2\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For a number of years I was involved with a university rocketry club called PSAS{% sidenote %}[Portland State Aerospace Society](http://psas.pdx.edu), a student aerospace engineering project at Portland State University. They build ultra-low-cost, open source rockets that feature very sophisticated amateur rocket avionics systems.{% endsidenote %}. One of the things I really liked to do was play with the data from the launches and learn how rockets and flight electronics work.\n",
"\n",
"\n",
"Our rockets carried an instrument on them called an **IMU** (Inertial Measument Unit). An IMU typically measures both acceleration and rotation-rate of an object in all directions so with some clever math you can re-create the exact position, velocity, and orientation of it over time. This is the only way to know where something is in space, and very important for rockets. IMUs have a problem though, they're not very precise.\n",
"\n",
"\n",
"Since our IMU is fixed to the rocket, {% marginnote %}![diagram of the rocket on it's side showing the layout of the internal components](img/L-12_overview.png) Overview of the rocket \"LV2.3\". The IMU is near the primary flight computer.{% endmarginnote %} which direction is \"up\" or \"left\", etc. relative to the Earth changes constantly as the rocket flies about. In order for the data to be useful we need to know which way we are pointed, which is why IMUs alway have some kind of gryoscope to account for rotation. Our particular IMU has rate-gyroscopes that can sense rotation rate, and so we integrate that once to get orientation. Since any integration will give an estimate that drifts from the true value over time, our IMU also includes a 3-axis _magnetometer_ as well.\n",
"\n",
"## 9DOF IMU\n",
"\n",
"This makes what is often what is refered to as a \"9DOF\" IMU, because it has \"nine degrees of freedom\". That would be _x, y, z_ accleration, _x, y, z_ rotation rate, and _x, y, z_ magnetic field. The reason to have a magnetometer is so you can use Earth's own magnetic field as a kind of guide to the orientation of the rocket. This doesn't instantly solve all problems in life, sadly. But it provides a good reference for the rough orientation of the rocket that can be used to produce a real-time estimate of rate-gyroscape drift, or 'bias', as we fly."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The magnetic field sensor in the rocket is sensitive, but because the Earth's field is so weak it's easily overwhelmed by local effects (metal screws, magnetic fields from nearby wires, etc.). In order to get good orientation data we need to undo{% marginnote %}![photo of two men awkwardly holding a large rocket body and an angle](img/L-12_ground_calibration.jpg) Members of the PSAS ground crew lifting and aranging the rocket around as many different orientations as possible before the flight.{% endmarginnote %} these local effects.\n",
"\n",
"\n",
"So a little before the flight we took the nearly complete rocket, powered the electronics up and then picked it up and tried to move it around in every direction.\n",
"\n",
"## Magnetometer Calibration\n",
"\n",
"What do we expect good magnetometer data to look like? The Earth's magnetic field shouldn't change much, so it should look like a single vector going through the IMU. If we rotate the rocket one way or another, the angel that the vector goes through will change, but it should stay the same strength. That means that the magnitude of the local magnetic filed should be constant, and it should measure it to be exactly the same as Earth's magnetic field.\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Earth's Field Strength\n",
"\n",
"\n",
"But what is the strength of Earth's magnetic field? It varies over time and over the surface of the Earth. We know where we launched from{% sidenote %}\n",
"Latitude: `43.79613280°` N\n",
"Longitude: `120.65175340°` W\n",
"Elevation: `1390.0` m Mean Sea Level\n",
"{% endsidenote %} and the date, so we can look up{% sidenote %}[NOAA's magnetic field calculator](https://www.ngdc.noaa.gov/geomag/magfield.shtml)\n",
"Model Used: `WMM2015`\n",
" {% endsidenote %} what the expected magnetic field should be:\n",
"\n",
"It's direction\n",
"\n",
"| | Declination (+E/-W) | Inclination (+D/-U) | Horizontal Intensity |\n",
"| -------------- | ------------------: | ------------------: | -------------------: | \n",
"| | 14.7990° | 66.5386° | 20,754.1 nT | \n",
"| _uncertainty_ | ±0.36° | ±0.22° | ±133 nT |\n",
"\n",
"\n",
"And as a vector\n",
"\n",
"| | North Comp (+N/-S) | East Comp (+E/-W) | Vertical Comp (+D/-U) |\n",
"| -------------- | -----------------: | ----------------: | --------------------: |\n",
"| | 20,065.7 nT | 5,301.2 nT | 47,819.4 nT |\n",
"| _uncertainty_ | ±138 nT | ±89 nT | ±165 nT |\n",
"\n",
"And finally the total strength\n",
"\n",
"| | Total Field |\n",
"| -------------- | ----------: |\n",
"| | 52,129.0 nT | \n",
"| _uncertainty_ | ±152 nT |"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Calibration Data\n",
"\n",
"That's what we _expect_ to see. What do we actually get?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import h5py\n",
"import numpy as np\n",
"from numpy import mgrid, pi, sin, cos\n",
"import matplotlib.pyplot as plt\n",
"from matplotlib import gridspec\n",
"from matplotlib.ticker import FuncFormatter\n",
"import matplotlib.patches as patches\n",
"from mpl_toolkits.mplot3d import Axes3D\n",
"from IPython.core.display import Markdown \n",
"%matplotlib inline\n",
"\n",
"def minsec(x, pos):\n",
" m = int(x/60)\n",
" s = int(x - (m*60))\n",
" return f\"{m:02d}:{s:02d}\"\n",
"\n",
"true_magnitude = 52.129\n",
" \n",
"# show a sphere\n",
"u, v = mgrid[0:2*pi:40j, 0:pi:20j]\n",
"radius = true_magnitude\n",
"x=cos(u)*sin(v)*radius\n",
"y=sin(u)*sin(v)*radius\n",
"z=cos(v)*radius"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"cal_data = h5py.File(\"data/L-12_calibration.hdf5\", \"r\")\n",
"adis = cal_data[\"ADIS\"]\n",
"\n",
"time = np.array(adis[\"time\"])\n",
"\n",
"m_raw_x = np.array(adis[\"mag_x\"]) * 1e6\n",
"m_raw_y = np.array(adis[\"mag_y\"]) * 1e6\n",
"m_raw_z = np.array(adis[\"mag_z\"]) * 1e6\n",
"\n",
"time_elapsed = time[-1] - time[0]\n",
"Markdown(f\"In the {time_elapsed/60:0.1f} minutes that we had the flight computer collecting data in our calibration run we recoreded {len(time):,} data points from the IMU\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mag = []\n",
"for i, t in enumerate(time):\n",
" mag.append(np.sqrt((m_raw_x[i]*m_raw_x[i]) + (m_raw_y[i]*m_raw_y[i]) + (m_raw_z[i]*m_raw_z[i])))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Looking over time at the _x, y, z_ values of the magnetometer and the mangitue compared to the NOAA predicted field we see it vary a lot."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"class": "fullwidth"
},
"outputs": [],
"source": [
"fig, ax1 = plt.subplots(figsize=(24,8))\n",
"plt.title(r\"IMU Magnetometer Calibration Run\")\n",
"plt.ylabel(r\"Magnetic Field [$ \\mu$T]\")\n",
"plt.xlabel(r\"Time [mm:ss]\")\n",
"\n",
"plt.plot(time, mag, 'k-', alpha=0.3, label=\"Magnitude\")\n",
"plt.plot([-100,5000], [52.129, 52.129], 'k-.', alpha=0.3, label=\"True Magnitude (NOAA estimate)\")\n",
"plt.plot(time, m_raw_x, lw=0.5, label=\"X ('Up')\")\n",
"plt.plot(time, m_raw_y, lw=0.5, label=\"Y\")\n",
"plt.plot(time, m_raw_z, lw=0.5, label=\"Z\")\n",
"\n",
"plt.xlim([0,1350])\n",
"plt.ylim([-100,100])\n",
"ax1.xaxis.set_major_formatter(FuncFormatter(minsec))\n",
"ax1.legend(loc=4)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is because we have a couple of problems. One is that the effective _center_ of our magnetometer values are pushed off to one side. And the other is that the values are skewed (or \"stretched\") off to one side as well. This is somewhat easier to see in 3D:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"fig = plt.figure(figsize=(24,24))\n",
"gs = gridspec.GridSpec(2, 2, width_ratios=[1, 1])\n",
"\n",
"ax1 = plt.subplot(gs[0])\n",
"plt.title(r\"Calibration Data XY\")\n",
"plt.xlabel(r\"Magnetic Field X [$ \\mu$T]\")\n",
"plt.ylabel(r\"Magnetic Field Y [$ \\mu$T]\")\n",
"ax1.plot(m_raw_x, m_raw_y, lw=0.8, label=\"\")\n",
"ax1.add_patch(patches.Circle((0, 0), 53, edgecolor=\"#cccccc\", linewidth=1.0, linestyle='--', fill=False))\n",
"plt.xlim([-80,80])\n",
"plt.ylim([-80,80])\n",
"\n",
"ax2 = plt.subplot(gs[1])\n",
"plt.title(r\"Calibration Data YZ\")\n",
"plt.xlabel(r\"Magnetic Field Y [$ \\mu$T]\")\n",
"plt.ylabel(r\"Magnetic Field Z [$ \\mu$T]\")\n",
"ax2.plot(m_raw_y, m_raw_z, lw=0.8, label=\"\")\n",
"ax2.add_patch(patches.Circle((0, 0), 53, edgecolor=\"#cccccc\", linewidth=1.0, linestyle='--', fill=False))\n",
"plt.xlim([-80,80])\n",
"plt.ylim([-80,80])\n",
"\n",
"ax3 = plt.subplot(gs[2])\n",
"plt.title(r\"Calibration Data XZ\")\n",
"plt.xlabel(r\"Magnetic Field X [$ \\mu$T]\")\n",
"plt.ylabel(r\"Magnetic Field Z [$ \\mu$T]\")\n",
"ax3.plot(m_raw_x, m_raw_z, lw=0.8, label=\"\")\n",
"ax3.add_patch(patches.Circle((0, 0), 53, edgecolor=\"#cccccc\", linewidth=1.0, linestyle='--', fill=False))\n",
"plt.xlim([-80,80])\n",
"plt.ylim([-80,80])\n",
"\n",
"ax4 = plt.subplot(gs[3], projection='3d')\n",
"plt.title(r\"Calibration Data XYZ\")\n",
"plt.xlabel(r\"Field Strength Y [$\\mu$T]\")\n",
"plt.ylabel(r\"Field Strength Z [$\\mu$T]\")\n",
"ax4.set_zlabel('Field Strength X [$\\mu$T]')\n",
"\n",
"ax4.plot_wireframe(x, y, z, color=\"k\", alpha=0.1, lw=0.2)\n",
"\n",
"ax4.plot(m_raw_y, m_raw_z, m_raw_x, '-', lw=0.5)\n",
"ax4.plot([0],[0],[0], 'g.')\n",
"\n",
"ax4.set_xlim(-60, 60)\n",
"ax4.set_ylim(-60, 60)\n",
"ax4.set_zlim(-60, 60)\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Correction\n",
"\n",
"The two parts of the correction are called \"Hard Iron\" (fixed center offset) and \"Soft Iron\" (streched sphere) corrections.\n",
"\n",
"### Hard Iron\n",
"\n",
"This is the simplest, we just find the midrange value of across the entire calibration dataset and make that the new '0'.\n",
"For our data that updated center should be:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"xcen = (max(m_raw_x) + min(m_raw_x)) / 2.0\n",
"ycen = (max(m_raw_y) + min(m_raw_y)) / 2.0\n",
"zcen = (max(m_raw_z) + min(m_raw_z)) / 2.0\n",
"\n",
"Markdown(f\"\"\"\n",
"| _x_ center [μT] | _y_ center [μT] | _z_ center [μT] |\n",
"| --------------: | --------------: | --------------: |\n",
"| {xcen:0.3f} | {ycen:0.3f} | {zcen:0.3f} |\n",
"\"\"\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Soft Iron\n",
"\n",
"This is a bit trickier because we want to fit an ellipsoid to the data, and then undo the stretch. Luckily an algorithm for this has been worked out.\n",
"\n",
"After fitting we end up with a matrix and offset vector. To invert the stretch we multiply the vector of each magnetometer by the correction matrix and offset.\n",
"\n",
"corrected_sample = **A** (sample - _b_)\n",
"\n",
"Where **A** is our correction matrix, and _b_ our offset vector."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def ellipsoid_fit(s):\n",
" ''' Estimate ellipsoid parameters from a set of points.\n",
"\n",
" Parameters\n",
" ----------\n",
" s : array_like\n",
" The samples (M,N) where M=3 (x,y,z) and N=number of samples.\n",
"\n",
" Returns\n",
" -------\n",
" M, n, d : array_like, array_like, float\n",
" The ellipsoid parameters M, n, d.\n",
"\n",
" References\n",
" ----------\n",
" .. [1] Qingde Li; Griffiths, J.G., \"Least squares ellipsoid specific\n",
" fitting,\" in Geometric Modeling and Processing, 2004.\n",
" Proceedings, vol., no., pp.335-340, 2004\n",
" '''\n",
"\n",
" # D (samples)\n",
" D = np.array([s[0]**2., s[1]**2., s[2]**2.,\n",
" 2.*s[1]*s[2], 2.*s[0]*s[2], 2.*s[0]*s[1],\n",
" 2.*s[0], 2.*s[1], 2.*s[2], np.ones_like(s[0])])\n",
"\n",
" # S, S_11, S_12, S_21, S_22 (eq. 11)\n",
" S = np.dot(D, D.T)\n",
" S_11 = S[:6,:6]\n",
" S_12 = S[:6,6:]\n",
" S_21 = S[6:,:6]\n",
" S_22 = S[6:,6:]\n",
"\n",
" # C (Eq. 8, k=4)\n",
" C = np.array([[-1, 1, 1, 0, 0, 0],\n",
" [ 1, -1, 1, 0, 0, 0],\n",
" [ 1, 1, -1, 0, 0, 0],\n",
" [ 0, 0, 0, -4, 0, 0],\n",
" [ 0, 0, 0, 0, -4, 0],\n",
" [ 0, 0, 0, 0, 0, -4]])\n",
"\n",
" # v_1 (eq. 15, solution)\n",
" E = np.dot(np.linalg.inv(C), S_11 - np.dot(S_12, np.dot(np.linalg.inv(S_22), S_21)))\n",
"\n",
" E_w, E_v = np.linalg.eig(E)\n",
"\n",
" v_1 = E_v[:, np.argmax(E_w)]\n",
" if v_1[0] < 0: v_1 = -v_1\n",
"\n",
" # v_2 (eq. 13, solution)\n",
" v_2 = np.dot(np.dot(-np.linalg.inv(S_22), S_21), v_1)\n",
"\n",
" # quadric-form parameters\n",
" M = np.array([[v_1[0], v_1[3], v_1[4]],\n",
" [v_1[3], v_1[1], v_1[5]],\n",
" [v_1[4], v_1[5], v_1[2]]])\n",
" n = np.array([[v_2[0]],\n",
" [v_2[1]],\n",
" [v_2[2]]])\n",
" d = v_2[3]\n",
"\n",
" return M, n, d"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# samples\n",
"s = []\n",
"for i, t in enumerate(time):\n",
" s.append((m_raw_x[i], m_raw_y[i], m_raw_z[i]))\n",
"\n",
"M, n, d = ellipsoid_fit(np.array(s).T)\n",
"\n",
"\n",
"\n",
"F = true_magnitude\n",
"\n",
"M_1 = np.linalg.inv(M)\n",
"b = np.dot(M_1, n)\n",
"A_1 = np.real(F / np.sqrt(np.dot(n.T, np.dot(M_1, n)) - d) * np.sqrt(M))\n",
"\n",
"print(A_1)\n",
"print(b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"a = np.array([[1.0, 3.0], [1.0, 4.0]])\n",
"r = np.linalg.sqrt(a)\n",
"print(r)\n",
"print(r.dot(r))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"celltoolbar": "Edit Metadata",
"kernelspec": {
"display_name": "Python 3",
"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.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading…
Cancel
Save