diff --git a/src/igrf/igrfpy/__init__.py b/src/igrf/igrfpy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/igrf/igrfpy/data/gh_data.json b/src/igrf/igrfpy/data/gh_data.json new file mode 100644 index 0000000..cf9e00a --- /dev/null +++ b/src/igrf/igrfpy/data/gh_data.json @@ -0,0 +1 @@ +{"1900": [-31543.0, -2298.0, 5922.0, -677.0, 2905.0, -1061.0, 924.0, 1121.0, 1022.0, -1469.0, -330.0, 1256.0, 3.0, 572.0, 523.0, 876.0, 628.0, 195.0, 660.0, -69.0, -361.0, -210.0, 134.0, -75.0, -184.0, 328.0, -210.0, 264.0, 53.0, 5.0, -33.0, -86.0, -124.0, -16.0, 3.0, 63.0, 61.0, -9.0, -11.0, 83.0, -217.0, 2.0, -58.0, -35.0, 59.0, 36.0, -90.0, -69.0, 70.0, -55.0, -45.0, 0.0, -13.0, 34.0, -10.0, -41.0, -1.0, -21.0, 28.0, 18.0, -12.0, 6.0, -22.0, 11.0, 8.0, 8.0, -4.0, -14.0, -9.0, 7.0, 1.0, -13.0, 2.0, 5.0, -9.0, 16.0, 5.0, -5.0, 8.0, -18.0, 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 8.0, 2.0, 10.0, -1.0, -2.0, -1.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 2.0, 4.0, 2.0, 0.0, 0.0, -6.0], "1905": [-31464.0, -2298.0, 5909.0, -728.0, 2928.0, -1086.0, 1041.0, 1065.0, 1037.0, -1494.0, -357.0, 1239.0, 34.0, 635.0, 480.0, 880.0, 643.0, 203.0, 653.0, -77.0, -380.0, -201.0, 146.0, -65.0, -192.0, 328.0, -193.0, 259.0, 56.0, -1.0, -32.0, -93.0, -125.0, -26.0, 11.0, 62.0, 60.0, -7.0, -11.0, 86.0, -221.0, 4.0, -57.0, -32.0, 57.0, 32.0, -92.0, -67.0, 70.0, -54.0, -46.0, 0.0, -14.0, 33.0, -11.0, -41.0, 0.0, -20.0, 28.0, 18.0, -12.0, 6.0, -22.0, 11.0, 8.0, 8.0, -4.0, -15.0, -9.0, 7.0, 1.0, -13.0, 2.0, 5.0, -8.0, 16.0, 5.0, -5.0, 8.0, -18.0, 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 8.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 2.0, 4.0, 2.0, 0.0, 0.0, -6.0], "1910": [-31354.0, -2297.0, 5898.0, -769.0, 2948.0, -1128.0, 1176.0, 1000.0, 1058.0, -1524.0, -389.0, 1223.0, 62.0, 705.0, 425.0, 884.0, 660.0, 211.0, 644.0, -90.0, -400.0, -189.0, 160.0, -55.0, -201.0, 327.0, -172.0, 253.0, 57.0, -9.0, -33.0, -102.0, -126.0, -38.0, 21.0, 62.0, 58.0, -5.0, -11.0, 89.0, -224.0, 5.0, -54.0, -29.0, 54.0, 28.0, -95.0, -65.0, 71.0, -54.0, -47.0, 1.0, -14.0, 32.0, -12.0, -40.0, 1.0, -19.0, 28.0, 18.0, -13.0, 6.0, -22.0, 11.0, 8.0, 8.0, -4.0, -15.0, -9.0, 6.0, 1.0, -13.0, 2.0, 5.0, -8.0, 16.0, 5.0, -5.0, 8.0, -18.0, 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 8.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 2.0, 4.0, 2.0, 0.0, 0.0, -6.0], "1915": [-31212.0, -2306.0, 5875.0, -802.0, 2956.0, -1191.0, 1309.0, 917.0, 1084.0, -1559.0, -421.0, 1212.0, 84.0, 778.0, 360.0, 887.0, 678.0, 218.0, 631.0, -109.0, -416.0, -173.0, 178.0, -51.0, -211.0, 327.0, -148.0, 245.0, 58.0, -16.0, -34.0, -111.0, -126.0, -51.0, 32.0, 61.0, 57.0, -2.0, -10.0, 93.0, -228.0, 8.0, -51.0, -26.0, 49.0, 23.0, -98.0, -62.0, 72.0, -54.0, -48.0, 2.0, -14.0, 31.0, -12.0, -38.0, 2.0, -18.0, 28.0, 19.0, -15.0, 6.0, -22.0, 11.0, 8.0, 8.0, -4.0, -15.0, -9.0, 6.0, 2.0, -13.0, 3.0, 5.0, -8.0, 16.0, 6.0, -5.0, 8.0, -18.0, 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 8.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 1.0, 4.0, 2.0, 0.0, 0.0, -6.0], "1920": [-31060.0, -2317.0, 5845.0, -839.0, 2959.0, -1259.0, 1407.0, 823.0, 1111.0, -1600.0, -445.0, 1205.0, 103.0, 839.0, 293.0, 889.0, 695.0, 220.0, 616.0, -134.0, -424.0, -153.0, 199.0, -57.0, -221.0, 326.0, -122.0, 236.0, 58.0, -23.0, -38.0, -119.0, -125.0, -62.0, 43.0, 61.0, 55.0, 0.0, -10.0, 96.0, -233.0, 11.0, -46.0, -22.0, 44.0, 18.0, -101.0, -57.0, 73.0, -54.0, -49.0, 2.0, -14.0, 29.0, -13.0, -37.0, 4.0, -16.0, 28.0, 19.0, -16.0, 6.0, -22.0, 11.0, 7.0, 8.0, -3.0, -15.0, -9.0, 6.0, 2.0, -14.0, 4.0, 5.0, -7.0, 17.0, 6.0, -5.0, 8.0, -19.0, 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 9.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 1.0, 4.0, 3.0, 0.0, 0.0, -6.0], "1925": [-30926.0, -2318.0, 5817.0, -893.0, 2969.0, -1334.0, 1471.0, 728.0, 1140.0, -1645.0, -462.0, 1202.0, 119.0, 881.0, 229.0, 891.0, 711.0, 216.0, 601.0, -163.0, -426.0, -130.0, 217.0, -70.0, -230.0, 326.0, -96.0, 226.0, 58.0, -28.0, -44.0, -125.0, -122.0, -69.0, 51.0, 61.0, 54.0, 3.0, -9.0, 99.0, -238.0, 14.0, -40.0, -18.0, 39.0, 13.0, -103.0, -52.0, 73.0, -54.0, -50.0, 3.0, -14.0, 27.0, -14.0, -35.0, 5.0, -14.0, 29.0, 19.0, -17.0, 6.0, -21.0, 11.0, 7.0, 8.0, -3.0, -15.0, -9.0, 6.0, 2.0, -14.0, 4.0, 5.0, -7.0, 17.0, 7.0, -5.0, 8.0, -19.0, 8.0, 10.0, -20.0, 1.0, 14.0, -11.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 9.0, 2.0, 10.0, 0.0, -2.0, -1.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 1.0, 4.0, 3.0, 0.0, 0.0, -6.0], "1930": [-30805.0, -2316.0, 5808.0, -951.0, 2980.0, -1424.0, 1517.0, 644.0, 1172.0, -1692.0, -480.0, 1205.0, 133.0, 907.0, 166.0, 896.0, 727.0, 205.0, 584.0, -195.0, -422.0, -109.0, 234.0, -90.0, -237.0, 327.0, -72.0, 218.0, 60.0, -32.0, -53.0, -131.0, -118.0, -74.0, 58.0, 60.0, 53.0, 4.0, -9.0, 102.0, -242.0, 19.0, -32.0, -16.0, 32.0, 8.0, -104.0, -46.0, 74.0, -54.0, -51.0, 4.0, -15.0, 25.0, -14.0, -34.0, 6.0, -12.0, 29.0, 18.0, -18.0, 6.0, -20.0, 11.0, 7.0, 8.0, -3.0, -15.0, -9.0, 5.0, 2.0, -14.0, 5.0, 5.0, -6.0, 18.0, 8.0, -5.0, 8.0, -19.0, 8.0, 10.0, -20.0, 1.0, 14.0, -12.0, 5.0, 12.0, -3.0, 1.0, -2.0, -2.0, 9.0, 3.0, 10.0, 0.0, -2.0, -2.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -2.0, 1.0, 4.0, 3.0, 0.0, 0.0, -6.0], "1935": [-30715.0, -2306.0, 5812.0, -1018.0, 2984.0, -1520.0, 1550.0, 586.0, 1206.0, -1740.0, -494.0, 1215.0, 146.0, 918.0, 101.0, 903.0, 744.0, 188.0, 565.0, -226.0, -415.0, -90.0, 249.0, -114.0, -241.0, 329.0, -51.0, 211.0, 64.0, -33.0, -64.0, -136.0, -115.0, -76.0, 64.0, 59.0, 53.0, 4.0, -8.0, 104.0, -246.0, 25.0, -25.0, -15.0, 25.0, 4.0, -106.0, -40.0, 74.0, -53.0, -52.0, 4.0, -17.0, 23.0, -14.0, -33.0, 7.0, -11.0, 29.0, 18.0, -19.0, 6.0, -19.0, 11.0, 7.0, 8.0, -3.0, -15.0, -9.0, 5.0, 1.0, -15.0, 6.0, 5.0, -6.0, 18.0, 8.0, -5.0, 7.0, -19.0, 8.0, 10.0, -20.0, 1.0, 15.0, -12.0, 5.0, 11.0, -3.0, 1.0, -3.0, -2.0, 9.0, 3.0, 11.0, 0.0, -2.0, -2.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -1.0, 2.0, 4.0, 3.0, 0.0, 0.0, -6.0], "1940": [-30654.0, -2292.0, 5821.0, -1106.0, 2981.0, -1614.0, 1566.0, 528.0, 1240.0, -1790.0, -499.0, 1232.0, 163.0, 916.0, 43.0, 914.0, 762.0, 169.0, 550.0, -252.0, -405.0, -72.0, 265.0, -141.0, -241.0, 334.0, -33.0, 208.0, 71.0, -33.0, -75.0, -141.0, -113.0, -76.0, 69.0, 57.0, 54.0, 4.0, -7.0, 105.0, -249.0, 33.0, -18.0, -15.0, 18.0, 0.0, -107.0, -33.0, 74.0, -53.0, -52.0, 4.0, -18.0, 20.0, -14.0, -31.0, 7.0, -9.0, 29.0, 17.0, -20.0, 5.0, -19.0, 11.0, 7.0, 8.0, -3.0, -14.0, -10.0, 5.0, 1.0, -15.0, 6.0, 5.0, -5.0, 19.0, 9.0, -5.0, 7.0, -19.0, 8.0, 10.0, -21.0, 1.0, 15.0, -12.0, 5.0, 11.0, -3.0, 1.0, -3.0, -2.0, 9.0, 3.0, 11.0, 1.0, -2.0, -2.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 6.0, -4.0, 4.0, 0.0, 0.0, -1.0, 2.0, 4.0, 3.0, 0.0, 0.0, -6.0], "1945": [-30594.0, -2285.0, 5810.0, -1244.0, 2990.0, -1702.0, 1578.0, 477.0, 1282.0, -1834.0, -499.0, 1255.0, 186.0, 913.0, -11.0, 944.0, 776.0, 144.0, 544.0, -276.0, -421.0, -55.0, 304.0, -178.0, -253.0, 346.0, -12.0, 194.0, 95.0, -20.0, -67.0, -142.0, -119.0, -82.0, 82.0, 59.0, 57.0, 6.0, 6.0, 100.0, -246.0, 16.0, -25.0, -9.0, 21.0, -16.0, -104.0, -39.0, 70.0, -40.0, -45.0, 0.0, -18.0, 0.0, 2.0, -29.0, 6.0, -10.0, 28.0, 15.0, -17.0, 29.0, -22.0, 13.0, 7.0, 12.0, -8.0, -21.0, -5.0, -12.0, 9.0, -7.0, 7.0, 2.0, -10.0, 18.0, 7.0, 3.0, 2.0, -11.0, 5.0, -21.0, -27.0, 1.0, 17.0, -11.0, 29.0, 3.0, -9.0, 16.0, 4.0, -3.0, 9.0, -4.0, 6.0, -3.0, 1.0, -4.0, 8.0, -3.0, 11.0, 5.0, 1.0, 1.0, 2.0, -20.0, -5.0, -1.0, -1.0, -6.0, 8.0, 6.0, -1.0, -4.0, -3.0, -2.0, 5.0, 0.0, -2.0, -2.0], "1950": [-30554.0, -2250.0, 5815.0, -1341.0, 2998.0, -1810.0, 1576.0, 381.0, 1297.0, -1889.0, -476.0, 1274.0, 206.0, 896.0, -46.0, 954.0, 792.0, 136.0, 528.0, -278.0, -408.0, -37.0, 303.0, -210.0, -240.0, 349.0, 3.0, 211.0, 103.0, -20.0, -87.0, -147.0, -122.0, -76.0, 80.0, 54.0, 57.0, -1.0, 4.0, 99.0, -247.0, 33.0, -16.0, -12.0, 12.0, -12.0, -105.0, -30.0, 65.0, -55.0, -35.0, 2.0, -17.0, 1.0, 0.0, -40.0, 10.0, -7.0, 36.0, 5.0, -18.0, 19.0, -16.0, 22.0, 15.0, 5.0, -4.0, -22.0, -1.0, 0.0, 11.0, -21.0, 15.0, -8.0, -13.0, 17.0, 5.0, -4.0, -1.0, -17.0, 3.0, -7.0, -24.0, -1.0, 19.0, -25.0, 12.0, 10.0, 2.0, 5.0, 2.0, -5.0, 8.0, -2.0, 8.0, 3.0, -11.0, 8.0, -7.0, -8.0, 4.0, 13.0, -1.0, -2.0, 13.0, -10.0, -4.0, 2.0, 4.0, -3.0, 12.0, 6.0, 3.0, -3.0, 2.0, 6.0, 10.0, 11.0, 3.0, 8.0], "1955": [-30500.0, -2215.0, 5820.0, -1440.0, 3003.0, -1898.0, 1581.0, 291.0, 1302.0, -1944.0, -462.0, 1288.0, 216.0, 882.0, -83.0, 958.0, 796.0, 133.0, 510.0, -274.0, -397.0, -23.0, 290.0, -230.0, -229.0, 360.0, 15.0, 230.0, 110.0, -23.0, -98.0, -152.0, -121.0, -69.0, 78.0, 47.0, 57.0, -9.0, 3.0, 96.0, -247.0, 48.0, -8.0, -16.0, 7.0, -12.0, -107.0, -24.0, 65.0, -56.0, -50.0, 2.0, -24.0, 10.0, -4.0, -32.0, 8.0, -11.0, 28.0, 9.0, -20.0, 18.0, -18.0, 11.0, 9.0, 10.0, -6.0, -15.0, -14.0, 5.0, 6.0, -23.0, 10.0, 3.0, -7.0, 23.0, 6.0, -4.0, 9.0, -13.0, 4.0, 9.0, -11.0, -4.0, 12.0, -5.0, 7.0, 2.0, 6.0, 4.0, -2.0, 1.0, 10.0, 2.0, 7.0, 2.0, -6.0, 5.0, 5.0, -3.0, -5.0, -4.0, -1.0, 0.0, 2.0, -8.0, -3.0, -2.0, 7.0, -4.0, 4.0, 1.0, -2.0, -3.0, 6.0, 7.0, -2.0, -1.0, 0.0, -3.0], "1960": [-30421.0, -2169.0, 5791.0, -1555.0, 3002.0, -1967.0, 1590.0, 206.0, 1302.0, -1992.0, -414.0, 1289.0, 224.0, 878.0, -130.0, 957.0, 800.0, 135.0, 504.0, -278.0, -394.0, 3.0, 269.0, -255.0, -222.0, 362.0, 16.0, 242.0, 125.0, -26.0, -117.0, -156.0, -114.0, -63.0, 81.0, 46.0, 58.0, -10.0, 1.0, 99.0, -237.0, 60.0, -1.0, -20.0, -2.0, -11.0, -113.0, -17.0, 67.0, -56.0, -55.0, 5.0, -28.0, 15.0, -6.0, -32.0, 7.0, -7.0, 23.0, 17.0, -18.0, 8.0, -17.0, 15.0, 6.0, 11.0, -4.0, -14.0, -11.0, 7.0, 2.0, -18.0, 10.0, 4.0, -5.0, 23.0, 10.0, 1.0, 8.0, -20.0, 4.0, 6.0, -18.0, 0.0, 12.0, -9.0, 2.0, 1.0, 0.0, 4.0, -3.0, -1.0, 9.0, -2.0, 8.0, 3.0, 0.0, -1.0, 5.0, 1.0, -3.0, 4.0, 4.0, 1.0, 0.0, 0.0, -1.0, 2.0, 4.0, -5.0, 6.0, 1.0, 1.0, -1.0, -1.0, 6.0, 2.0, 0.0, 0.0, -7.0], "1965": [-30334.0, -2119.0, 5776.0, -1662.0, 2997.0, -2016.0, 1594.0, 114.0, 1297.0, -2038.0, -404.0, 1292.0, 240.0, 856.0, -165.0, 957.0, 804.0, 148.0, 479.0, -269.0, -390.0, 13.0, 252.0, -269.0, -219.0, 358.0, 19.0, 254.0, 128.0, -31.0, -126.0, -157.0, -97.0, -62.0, 81.0, 45.0, 61.0, -11.0, 8.0, 100.0, -228.0, 68.0, 4.0, -32.0, 1.0, -8.0, -111.0, -7.0, 75.0, -57.0, -61.0, 4.0, -27.0, 13.0, -2.0, -26.0, 6.0, -6.0, 26.0, 13.0, -23.0, 1.0, -12.0, 13.0, 5.0, 7.0, -4.0, -12.0, -14.0, 9.0, 0.0, -16.0, 8.0, 4.0, -1.0, 24.0, 11.0, -3.0, 4.0, -17.0, 8.0, 10.0, -22.0, 2.0, 15.0, -13.0, 7.0, 10.0, -4.0, -1.0, -5.0, -1.0, 10.0, 5.0, 10.0, 1.0, -4.0, -2.0, 1.0, -2.0, -3.0, 2.0, 2.0, 1.0, -5.0, 2.0, -2.0, 6.0, 4.0, -4.0, 4.0, 0.0, 0.0, -2.0, 2.0, 3.0, 2.0, 0.0, 0.0, -6.0], "1970": [-30220.0, -2068.0, 5737.0, -1781.0, 3000.0, -2047.0, 1611.0, 25.0, 1287.0, -2091.0, -366.0, 1278.0, 251.0, 838.0, -196.0, 952.0, 800.0, 167.0, 461.0, -266.0, -395.0, 26.0, 234.0, -279.0, -216.0, 359.0, 26.0, 262.0, 139.0, -42.0, -139.0, -160.0, -91.0, -56.0, 83.0, 43.0, 64.0, -12.0, 15.0, 100.0, -212.0, 72.0, 2.0, -37.0, 3.0, -6.0, -112.0, 1.0, 72.0, -57.0, -70.0, 1.0, -27.0, 14.0, -4.0, -22.0, 8.0, -2.0, 23.0, 13.0, -23.0, -2.0, -11.0, 14.0, 6.0, 7.0, -2.0, -15.0, -13.0, 6.0, -3.0, -17.0, 5.0, 6.0, 0.0, 21.0, 11.0, -6.0, 3.0, -16.0, 8.0, 10.0, -21.0, 2.0, 16.0, -12.0, 6.0, 10.0, -4.0, -1.0, -5.0, 0.0, 10.0, 3.0, 11.0, 1.0, -2.0, -1.0, 1.0, -3.0, -3.0, 1.0, 2.0, 1.0, -5.0, 3.0, -1.0, 4.0, 6.0, -4.0, 4.0, 0.0, 1.0, -1.0, 0.0, 3.0, 3.0, 1.0, -1.0, -4.0], "1975": [-30100.0, -2013.0, 5675.0, -1902.0, 3010.0, -2067.0, 1632.0, -68.0, 1276.0, -2144.0, -333.0, 1260.0, 262.0, 830.0, -223.0, 946.0, 791.0, 191.0, 438.0, -265.0, -405.0, 39.0, 216.0, -288.0, -218.0, 356.0, 31.0, 264.0, 148.0, -59.0, -152.0, -159.0, -83.0, -49.0, 88.0, 45.0, 66.0, -13.0, 28.0, 99.0, -198.0, 75.0, 1.0, -41.0, 6.0, -4.0, -111.0, 11.0, 71.0, -56.0, -77.0, 1.0, -26.0, 16.0, -5.0, -14.0, 10.0, 0.0, 22.0, 12.0, -23.0, -5.0, -12.0, 14.0, 6.0, 6.0, -1.0, -16.0, -12.0, 4.0, -8.0, -19.0, 4.0, 6.0, 0.0, 18.0, 10.0, -10.0, 1.0, -17.0, 7.0, 10.0, -21.0, 2.0, 16.0, -12.0, 7.0, 10.0, -4.0, -1.0, -5.0, -1.0, 10.0, 4.0, 11.0, 1.0, -3.0, -2.0, 1.0, -3.0, -3.0, 1.0, 2.0, 1.0, -5.0, 3.0, -2.0, 4.0, 5.0, -4.0, 4.0, -1.0, 1.0, -1.0, 0.0, 3.0, 3.0, 1.0, -1.0, -5.0], "1980": [-29992.0, -1956.0, 5604.0, -1997.0, 3027.0, -2129.0, 1663.0, -200.0, 1281.0, -2180.0, -336.0, 1251.0, 271.0, 833.0, -252.0, 938.0, 782.0, 212.0, 398.0, -257.0, -419.0, 53.0, 199.0, -297.0, -218.0, 357.0, 46.0, 261.0, 150.0, -74.0, -151.0, -162.0, -78.0, -48.0, 92.0, 48.0, 66.0, -15.0, 42.0, 93.0, -192.0, 71.0, 4.0, -43.0, 14.0, -2.0, -108.0, 17.0, 72.0, -59.0, -82.0, 2.0, -27.0, 21.0, -5.0, -12.0, 16.0, 1.0, 18.0, 11.0, -23.0, -2.0, -10.0, 18.0, 6.0, 7.0, 0.0, -18.0, -11.0, 4.0, -7.0, -22.0, 4.0, 9.0, 3.0, 16.0, 6.0, -13.0, -1.0, -15.0, 5.0, 10.0, -21.0, 1.0, 16.0, -12.0, 9.0, 9.0, -5.0, -3.0, -6.0, -1.0, 9.0, 7.0, 10.0, 2.0, -6.0, -5.0, 2.0, -4.0, -4.0, 1.0, 2.0, 0.0, -5.0, 3.0, -2.0, 6.0, 5.0, -4.0, 3.0, 0.0, 1.0, -1.0, 2.0, 4.0, 3.0, 0.0, 0.0, -6.0], "1985": [-29873.0, -1905.0, 5500.0, -2072.0, 3044.0, -2197.0, 1687.0, -306.0, 1296.0, -2208.0, -310.0, 1247.0, 284.0, 829.0, -297.0, 936.0, 780.0, 232.0, 361.0, -249.0, -424.0, 69.0, 170.0, -297.0, -214.0, 355.0, 47.0, 253.0, 150.0, -93.0, -154.0, -164.0, -75.0, -46.0, 95.0, 53.0, 65.0, -16.0, 51.0, 88.0, -185.0, 69.0, 4.0, -48.0, 16.0, -1.0, -102.0, 21.0, 74.0, -62.0, -83.0, 3.0, -27.0, 24.0, -2.0, -6.0, 20.0, 4.0, 17.0, 10.0, -23.0, 0.0, -7.0, 21.0, 6.0, 8.0, 0.0, -19.0, -11.0, 5.0, -9.0, -23.0, 4.0, 11.0, 4.0, 14.0, 4.0, -15.0, -4.0, -11.0, 5.0, 10.0, -21.0, 1.0, 15.0, -12.0, 9.0, 9.0, -6.0, -3.0, -6.0, -1.0, 9.0, 7.0, 9.0, 1.0, -7.0, -5.0, 2.0, -4.0, -4.0, 1.0, 3.0, 0.0, -5.0, 3.0, -2.0, 6.0, 5.0, -4.0, 3.0, 0.0, 1.0, -1.0, 2.0, 4.0, 3.0, 0.0, 0.0, -6.0], "1990": [-29775.0, -1848.0, 5406.0, -2131.0, 3059.0, -2279.0, 1686.0, -373.0, 1314.0, -2239.0, -284.0, 1248.0, 293.0, 802.0, -352.0, 939.0, 780.0, 247.0, 325.0, -240.0, -423.0, 84.0, 141.0, -299.0, -214.0, 353.0, 46.0, 245.0, 154.0, -109.0, -153.0, -165.0, -69.0, -36.0, 97.0, 61.0, 65.0, -16.0, 59.0, 82.0, -178.0, 69.0, 3.0, -52.0, 18.0, 1.0, -96.0, 24.0, 77.0, -64.0, -80.0, 2.0, -26.0, 26.0, 0.0, -1.0, 21.0, 5.0, 17.0, 9.0, -23.0, 0.0, -4.0, 23.0, 5.0, 10.0, -1.0, -19.0, -10.0, 6.0, -12.0, -22.0, 3.0, 12.0, 4.0, 12.0, 2.0, -16.0, -6.0, -10.0, 4.0, 9.0, -20.0, 1.0, 15.0, -12.0, 11.0, 9.0, -7.0, -4.0, -7.0, -2.0, 9.0, 7.0, 8.0, 1.0, -7.0, -6.0, 2.0, -3.0, -4.0, 2.0, 2.0, 1.0, -5.0, 3.0, -2.0, 6.0, 4.0, -4.0, 3.0, 0.0, 1.0, -2.0, 3.0, 3.0, 3.0, -1.0, 0.0, -6.0], "1995": [-29692.0, -1784.0, 5306.0, -2200.0, 3070.0, -2366.0, 1681.0, -413.0, 1335.0, -2267.0, -262.0, 1249.0, 302.0, 759.0, -427.0, 940.0, 780.0, 262.0, 290.0, -236.0, -418.0, 97.0, 122.0, -306.0, -214.0, 352.0, 46.0, 235.0, 165.0, -118.0, -143.0, -166.0, -55.0, -17.0, 107.0, 68.0, 67.0, -17.0, 68.0, 72.0, -170.0, 67.0, -1.0, -58.0, 19.0, 1.0, -93.0, 36.0, 77.0, -72.0, -69.0, 1.0, -25.0, 28.0, 4.0, 5.0, 24.0, 4.0, 17.0, 8.0, -24.0, -2.0, -6.0, 25.0, 6.0, 11.0, -6.0, -21.0, -9.0, 8.0, -14.0, -23.0, 9.0, 15.0, 6.0, 11.0, -5.0, -16.0, -7.0, -4.0, 4.0, 9.0, -20.0, 3.0, 15.0, -10.0, 12.0, 8.0, -6.0, -8.0, -8.0, -1.0, 8.0, 10.0, 5.0, -2.0, -8.0, -8.0, 3.0, -3.0, -6.0, 1.0, 2.0, 0.0, -4.0, 4.0, -1.0, 5.0, 4.0, -5.0, 2.0, -1.0, 2.0, -2.0, 5.0, 1.0, 1.0, -2.0, 0.0, -7.0, 75.0, 0.0], "2000": [-29619.4, -1728.2, 5186.1, -2267.7, 3068.4, -2481.6, 1670.9, -458.0, 1339.6, -2288.0, -227.6, 1252.1, 293.4, 714.5, -491.1, 932.3, 786.8, 272.6, 250.0, -231.9, -403.0, 119.8, 111.3, -303.8, -218.8, 351.4, 43.8, 222.3, 171.9, -130.4, -133.1, -168.6, -39.3, -12.9, 106.3, 72.3, 68.2, -17.4, 74.2, 63.7, -160.9, 65.1, -5.9, -61.2, 16.9, 0.7, -90.4, 43.8, 79.0, -74.0, -64.6, 0.0, -24.2, 33.3, 6.2, 9.1, 24.0, 6.9, 14.8, 7.3, -25.4, -1.2, -5.8, 24.4, 6.6, 11.9, -9.2, -21.5, -7.9, 8.5, -16.6, -21.5, 9.1, 15.5, 7.0, 8.9, -7.9, -14.9, -7.0, -2.1, 5.0, 9.4, -19.7, 3.0, 13.4, -8.4, 12.5, 6.3, -6.2, -8.9, -8.4, -1.5, 8.4, 9.3, 3.8, -4.3, -8.2, -8.2, 4.8, -2.6, -6.0, 1.7, 1.7, 0.0, -3.1, 4.0, -0.5, 4.9, 3.7, -5.9, 1.0, -1.2, 2.0, -2.9, 4.2, 0.2, 0.3, -2.2, -1.1, -7.4, 2.7, -1.7, 0.1, -1.9, 1.3, 1.5, -0.9, -0.1, -2.6, 0.1, 0.9, -0.7, -0.7, 0.7, -2.8, 1.7, -0.9, 0.1, -1.2, 1.2, -1.9, 4.0, -0.9, -2.2, -0.3, -0.4, 0.2, 0.3, 0.9, 2.5, -0.2, -2.6, 0.9, 0.7, -0.5, 0.3, 0.3, 0.0, -0.3, 0.0, -0.4, 0.3, -0.1, -0.9, -0.2, -0.4, -0.4, 0.8, -0.2, -0.9, -0.9, 0.3, 0.2, 0.1, 1.8, -0.4, -0.4, 1.3, -1.0, -0.4, -0.1, 0.7, 0.7, -0.4, 0.3, 0.3, 0.6, -0.1, 0.3, 0.4, -0.2, 0.0, -0.5, 0.1, -0.9], "2005": [-29554.63, -1669.05, 5077.99, -2337.24, 3047.69, -2594.5, 1657.76, -515.43, 1336.3, -2305.83, -198.86, 1246.39, 269.72, 672.51, -524.72, 920.55, 797.96, 282.07, 210.65, -225.23, -379.86, 145.15, 100.0, -305.36, -227.0, 354.41, 42.72, 208.95, 180.25, -136.54, -123.45, -168.05, -19.57, -13.55, 103.85, 73.6, 69.56, -20.33, 76.74, 54.75, -151.34, 63.63, -14.58, -63.53, 14.58, 0.24, -86.36, 50.94, 79.88, -74.46, -61.14, -1.65, -22.57, 38.73, 6.82, 12.3, 25.35, 9.37, 10.93, 5.42, -26.32, 1.94, -4.64, 24.8, 7.62, 11.2, -11.73, -20.88, -6.88, 9.83, -18.11, -19.71, 10.17, 16.22, 9.36, 7.61, -11.25, -12.76, -4.87, -0.06, 5.58, 9.76, -20.11, 3.58, 12.69, -6.94, 12.67, 5.01, -6.72, -10.76, -8.16, -1.25, 8.1, 8.76, 2.92, -6.66, -7.73, -9.22, 6.01, -2.17, -6.12, 2.19, 1.42, 0.1, -2.35, 4.46, -0.15, 4.76, 3.06, -6.58, 0.29, -1.01, 2.06, -3.47, 3.77, -0.86, -0.21, -2.31, -2.09, -7.93, 2.95, -1.6, 0.26, -1.88, 1.44, 1.44, -0.77, -0.31, -2.27, 0.29, 0.9, -0.79, -0.58, 0.53, -2.69, 1.8, -1.08, 0.16, -1.58, 0.96, -1.9, 3.99, -1.39, -2.15, -0.29, -0.55, 0.21, 0.23, 0.89, 2.38, -0.38, -2.63, 0.96, 0.61, -0.3, 0.4, 0.46, 0.01, -0.35, 0.02, -0.36, 0.28, 0.08, -0.87, -0.49, -0.34, -0.08, 0.88, -0.16, -0.88, -0.76, 0.3, 0.33, 0.28, 1.72, -0.43, -0.54, 1.18, -1.07, -0.37, -0.04, 0.75, 0.63, -0.26, 0.21, 0.35, 0.53, -0.05, 0.38, 0.41, -0.22, -0.1, -0.57, -0.18, -0.82], "2010": [-29496.57, -1586.42, 4944.26, -2396.06, 3026.34, -2708.54, 1668.17, -575.73, 1339.85, -2326.54, -160.4, 1232.1, 251.75, 633.73, -537.03, 912.66, 808.97, 286.48, 166.58, -211.03, -356.83, 164.46, 89.4, -309.72, -230.87, 357.29, 44.58, 200.26, 189.01, -141.05, -118.06, -163.17, -0.01, -8.03, 101.04, 72.78, 68.69, -20.9, 75.92, 44.18, -141.4, 61.54, -22.83, -66.26, 13.1, 3.02, -78.09, 55.4, 80.44, -75.0, -57.8, -4.55, -21.2, 45.24, 6.54, 14.0, 24.96, 10.46, 7.03, 1.64, -27.61, 4.92, -3.28, 24.41, 8.21, 10.84, -14.5, -20.03, -5.59, 11.83, -19.34, -17.41, 11.61, 16.71, 10.85, 6.96, -14.05, -10.74, -3.54, 1.64, 5.5, 9.45, -20.54, 3.45, 11.51, -5.27, 12.75, 3.13, -7.14, -12.38, -7.42, -0.76, 7.97, 8.43, 2.14, -8.42, -6.08, -10.08, 7.01, -1.94, -6.24, 2.73, 0.89, -0.1, -1.07, 4.71, -0.16, 4.44, 2.45, -7.22, -0.33, -0.96, 2.13, -3.95, 3.09, -1.99, -1.03, -1.97, -2.8, -8.31, 3.05, -1.48, 0.13, -2.03, 1.67, 1.65, -0.66, -0.51, -1.76, 0.54, 0.85, -0.79, -0.39, 0.37, -2.51, 1.79, -1.27, 0.12, -2.11, 0.75, -1.94, 3.75, -1.86, -2.12, -0.21, -0.87, 0.3, 0.27, 1.04, 2.13, -0.63, -2.49, 0.95, 0.49, -0.11, 0.59, 0.52, 0.0, -0.39, 0.13, -0.37, 0.27, 0.21, -0.86, -0.77, -0.23, 0.04, 0.87, -0.09, -0.89, -0.87, 0.31, 0.3, 0.42, 1.66, -0.45, -0.59, 1.08, -1.14, -0.31, -0.07, 0.78, 0.54, -0.18, 0.1, 0.38, 0.49, 0.02, 0.44, 0.42, -0.25, -0.26, -0.53, -0.26, -0.79], "2015": [-29441.46, -1501.77, 4795.99, -2445.88, 3012.2, -2845.41, 1676.35, -642.17, 1350.33, -2352.26, -115.29, 1225.85, 245.04, 581.69, -538.7, 907.42, 813.68, 283.54, 120.49, -188.43, -334.85, 180.95, 70.38, -329.23, -232.91, 360.14, 46.98, 192.35, 196.98, -140.94, -119.14, -157.4, 15.98, 4.3, 100.12, 69.55, 67.57, -20.61, 72.79, 33.3, -129.85, 58.74, -28.93, -66.64, 13.14, 7.35, -70.85, 62.41, 81.29, -75.99, -54.27, -6.79, -19.53, 51.82, 5.59, 15.07, 24.45, 9.32, 3.27, -2.88, -27.5, 6.61, -2.32, 23.98, 8.89, 10.04, -16.78, -18.26, -3.16, 13.18, -20.56, -14.6, 13.33, 16.16, 11.76, 5.69, -15.98, -9.1, -2.02, 2.26, 5.33, 8.83, -21.77, 3.02, 10.76, -3.22, 11.74, 0.67, -6.74, -13.2, -6.88, -0.1, 7.79, 8.68, 1.04, -9.06, -3.89, -10.54, 8.44, -2.01, -6.26, 3.28, 0.17, -0.4, 0.55, 4.55, -0.55, 4.4, 1.7, -7.92, -0.67, -0.61, 2.13, -4.16, 2.33, -2.85, -1.8, -1.12, -3.59, -8.72, 3.0, -1.4, 0.0, -2.3, 2.11, 2.08, -0.6, -0.79, -1.05, 0.58, 0.76, -0.7, -0.2, 0.14, -2.12, 1.7, -1.44, -0.22, -2.57, 0.44, -2.01, 3.49, -2.34, -2.09, -0.16, -1.08, 0.46, 0.37, 1.23, 1.75, -0.89, -2.19, 0.85, 0.27, 0.1, 0.72, 0.54, -0.09, -0.37, 0.29, -0.43, 0.23, 0.22, -0.89, -0.94, -0.16, -0.03, 0.72, -0.02, -0.92, -0.88, 0.42, 0.49, 0.63, 1.56, -0.42, -0.5, 0.96, -1.24, -0.19, -0.1, 0.81, 0.42, -0.13, -0.04, 0.38, 0.48, 0.08, 0.48, 0.46, -0.3, -0.35, -0.43, -0.36, -0.71], "2020": [-29404.8, -1450.9, 4652.5, -2499.6, 2982.0, -2991.6, 1677.0, -734.6, 1363.2, -2381.2, -82.1, 1236.2, 241.9, 525.7, -543.4, 903.0, 809.5, 281.9, 86.3, -158.4, -309.4, 199.7, 48.0, -349.7, -234.3, 363.2, 47.7, 187.8, 208.3, -140.7, -121.2, -151.2, 32.3, 13.5, 98.9, 66.0, 65.5, -19.1, 72.9, 25.1, -121.5, 52.8, -36.2, -64.5, 13.5, 8.9, -64.7, 68.1, 80.6, -76.7, -51.5, -8.2, -16.9, 56.5, 2.2, 15.8, 23.5, 6.4, -2.2, -7.2, -27.2, 9.8, -1.8, 23.7, 9.7, 8.4, -17.6, -15.3, -0.5, 12.8, -21.1, -11.7, 15.3, 14.9, 13.7, 3.6, -16.5, -6.9, -0.3, 2.8, 5.0, 8.4, -23.4, 2.9, 11.0, -1.5, 9.8, -1.1, -5.1, -13.2, -6.3, 1.1, 7.8, 8.8, 0.4, -9.3, -1.4, -11.9, 9.6, -1.9, -6.2, 3.4, -0.1, -0.2, 1.7, 3.6, -0.9, 4.8, 0.7, -8.6, -0.9, -0.1, 1.9, -4.3, 1.4, -3.4, -2.4, -0.1, -3.8, -8.8, 3.0, -1.4, 0.0, -2.5, 2.5, 2.3, -0.6, -0.9, -0.4, 0.3, 0.6, -0.7, -0.2, -0.1, -1.7, 1.4, -1.6, -0.6, -3.0, 0.2, -2.0, 3.1, -2.6, -2.0, -0.1, -1.2, 0.5, 0.5, 1.3, 1.4, -1.2, -1.8, 0.7, 0.1, 0.3, 0.8, 0.5, -0.2, -0.3, 0.6, -0.5, 0.2, 0.1, -0.9, -1.1, 0.0, -0.3, 0.5, 0.1, -0.9, -0.9, 0.5, 0.6, 0.7, 1.4, -0.3, -0.4, 0.8, -1.3, 0.0, -0.1, 0.8, 0.3, 0.0, -0.1, 0.4, 0.5, 0.1, 0.5, 0.5, -0.4, -0.5, -0.4, -0.4, -0.6], "2022": [5.7, 7.4, -25.9, -11.0, -7.0, -30.2, -2.1, -22.4, 2.2, -5.9, 6.0, 3.1, -1.1, -12.0, 0.5, -1.2, -1.6, -0.1, -5.9, 6.5, 5.2, 3.6, -5.1, -5.0, -0.3, 0.5, 0.0, -0.6, 2.5, 0.2, -0.6, 1.3, 3.0, 0.9, 0.3, -0.5, -0.3, 0.0, 0.4, -1.6, 1.3, -1.3, -1.4, 0.8, 0.0, 0.0, 0.9, 1.0, -0.1, -0.2, 0.6, 0.0, 0.6, 0.7, -0.8, 0.1, -0.2, -0.5, -1.1, -0.8, 0.1, 0.8, 0.3, 0.0, 0.1, -0.2, -0.1, 0.6, 0.4, -0.2, -0.1, 0.5, 0.4, -0.3, 0.3, -0.4, -0.1, 0.5, 0.4, 0.0, 115.0, 0.0]} \ No newline at end of file diff --git a/src/igrf/igrfpy/igrf13.py b/src/igrf/igrfpy/igrf13.py new file mode 100644 index 0000000..1a0547d --- /dev/null +++ b/src/igrf/igrfpy/igrf13.py @@ -0,0 +1,365 @@ +import numpy as np +import pandas as pd +import json +import os +import datetime +from dateutil.parser import parse + + +def load_dict_from_json(filename): + with open(filename, 'r') as json_file: + return json.load(json_file) + + +def IGRF13(lat, lon, alt, dates, isv=0, itype=1): + """ + This is a Python-reconstructed function by uho-33, based on the original Fortran code: + https://github.com/space-physics/igrf/blob/main/src/igrf/fortran/igrf13.f. + + The model is valid from 1900.0 to 2025.0. Values from 1945.0 to 2015.0 are definitive, + while those outside this range are non-definitive. + + Parameters + ---------- + lat : float, list, or numpy.ndarray + Latitude(s) of the point(s) in degrees. Positive values indicate north latitude. + + lon : float, list, or numpy.ndarray + Longitude(s) of the point(s) in degrees. Positive values indicate east longitude. + + alt : float, list, or numpy.ndarray + Altitude(s) in kilometers: + - If `itype = 1`: Altitude above sea level. + - If `itype = 2`: Distance from Earth's center (> 3485 km). + + dates : float, str, int, datetime, list, or numpy.ndarray + Date(s) for the IGRF calculation. Supported formats include: + - `float`: Decimal year (e.g., 2016.5). + - `str`: Date in 'YYYYMMDD' format (e.g., '20160708'). + - `int`: Year as an integer (e.g., 2016). + - `datetime`: `datetime.datetime` or `datetime.date`. + - `list` or `numpy.ndarray`: A collection of the above types. + + isv : int, optional (default=0) + Type of values to compute: + - `0`: Main-field values. + - `1`: Secular variation values. + + itype : int, optional (default=1) + Coordinate system of the input: + - `1`: Geodetic (spheroid). + - `2`: Geocentric (sphere). + + Returns + ------- + numpy.ndarray + A 2D array of shape `(4, N)`, where: + - The first dimension (size 4) represents magnetic field components: + - `[0]`: `B_north` – North component (nT) if `isv = 0`, nT/year if `isv = 1`. + - `[1]`: `B_east` – East component (nT) if `isv = 0`, nT/year if `isv = 1`. + - `[2]`: `B_vert` – Vertical (earthward) component (nT) if `isv = 0`, nT/year if `isv = 1`. + - `[3]`: `B_total` – Total intensity (nT) if `isv = 0`, nT/year if `isv = 1`. + - The second dimension (size N) corresponds to the number of input points. + + Examples + -------- + Single point calculation for a specific date: + >>> IGRF13(30.0, 232.0, 35786, 2016.5) + Output: + [[ 85.76211027] + [ 17.57562939] + [123.91279388] + [151.71823487]] + + Multiple points and dates: + >>> IGRF13([30.0, 40.0], [232.0, 250.0], [35786, 40000], ['20160708', '20170809']) + Output: + [[ 81.3243117 52.36266943] + [ 9.52994813 6.89129736] + [124.99133933 113.81947292] + [149.42321939 125.47594011]] + + + """ + # Import gh data + script_path = os.path.realpath(__file__) + script_directory = os.path.dirname(script_path) + gh = load_dict_from_json(os.path.join(script_directory, 'data/gh_data.json')) + + # Ensure the variables are 1-dimensional arrays + if not isinstance(dates, (list, np.ndarray)): + dates = [dates] + lat =[lat] + lon = [lon] + alt = [alt] + lat, lon, alt, dates = map(np.array,[lat, lon, alt, dates]) + + # Check if all input arrays have the same shape + if not (lat.shape == lon.shape == alt.shape == dates.shape): + raise ValueError(f"Input arrays must have the same shape. " + f"Received shapes: lat={lat.shape}, lon={lon.shape}, alt={alt.shape}, dates={dates.shape}") + + # Convert dates to decimal years + dates = datetime2yeardec(dates) + + # Initialize output arrays + B_north = np.zeros((len(dates))) + B_east = np.zeros((len(dates))) + B_vert = np.zeros((len(dates))) + B_total = np.zeros((len(dates))) + + colat = 90 - lat + elong = lon + + out_of_bounds = (dates < 1900.0) | (dates > 2030.0) + if np.any(out_of_bounds): + raise ValueError("Error: Some dates are out of bounds (1900-2030):{}".format(set(map(int, dates[out_of_bounds])))) + + # Vectorized warning for dates after 2025 + accuracy_warning = dates > 2025.0 + if np.any(accuracy_warning): + print("Warning: Accuracy may be reduced for year: {}".format(set(map(int, dates[accuracy_warning])))) + + # Calculate time-related variables + t = np.zeros_like(dates) + tc = np.zeros_like(dates) + mask_2020 = dates >= 2020.0 + t = np.where(mask_2020, + 1.0 if isv==1 else dates-2020, + 0.2 if isv==1 else (dates - 1900)%5/5 ) + tc = np.where(mask_2020, + 0.0 if isv==1 else 1.0, + -0.2 if isv==1 else 1.0-t) + + nmx = np.where(dates<2000, 10, 13) + kmx = (nmx+1)*(nmx+2)/2 + + + # Initial trigonometric calculations + cl = np.zeros((len(dates),13)) + sl = np.zeros((len(dates),13)) + colat_rad, elong_rad = np.radians(colat), np.radians(elong) + ct, st = np.cos(colat_rad), np.sin(colat_rad) + cl[:,0] = np.cos(elong_rad) + sl[:,0] = np.sin(elong_rad) + cd = 1. + sd = 0. + + # Convert geocentric to geographic coordinates if necessary + if itype != 2: + a2 = 40680631.6 + b2 = 40408296.0 + one = a2*st*st + two = b2*ct*ct + three = one + two + rho = np.sqrt(three) + r = np.sqrt(alt * (alt + 2.0 * rho) + (a2 * one + b2 * two) / (three)) + cd = (alt + rho) / r + sd = ((a2 - b2) / rho) * ct * st / r + ct, st = ct * cd - st * sd, st * cd + ct * sd + else: + r = alt + ratio = 6371.2/r + rr = ratio**2 + + max_kmx = int(np.max(kmx)) + p = np.zeros((len(dates), max_kmx)) + q = np.zeros((len(dates), max_kmx)) + p[:,0] = 1. + p[:,2] = st + q[:,0] = 0. + q[:,2] = ct + fn, gn = np.zeros(len(dates)), np.zeros(len(dates)) + l, m, n = np.ones(len(dates)), np.ones(len(dates)), np.zeros(len(dates)) + fm = m + year = np.where(mask_2020, 2020, dates//5*5) + year_next = np.where(mask_2020, 2022, year) + gh_values_before = np.array([gh[str(int(key))] for key in year]) + gh_values_after = np.array([gh[str(int(key))] for key in year_next]) + + + for k in range(1, max_kmx): + # one, two, and three are used to store intermediate values for calculations + one, two, three = np.zeros(len(dates)), np.zeros(len(dates)), np.zeros(len(dates)) + + valid_mask = k <= kmx + reset_mask = (n < m) & valid_mask + m = np.int32(np.where(reset_mask, 0, m)) + n = np.int32(np.where(reset_mask, n+1, n)) + rr = np.where(reset_mask, rr*ratio, rr) + fn = np.where(reset_mask, n, fn) + gn = np.where(reset_mask, n-1, gn) + + fm = np.where(valid_mask, m, fm) + + equal_mask = (m == n) & valid_mask + equal_and_not2_mask = equal_mask & (k != 2) & valid_mask + if np.any(equal_and_not2_mask): + one[equal_and_not2_mask] = np.sqrt(1.0 - 0.5 / fm[equal_and_not2_mask]) + j = np.int32(np.where(equal_and_not2_mask, k-n-1, 0)) + p[:,k] = np.where(equal_and_not2_mask, + one * st *p[np.arange(len(j)),j], + p[:,k]) + q[:,k] = np.where(equal_and_not2_mask, + one * (st * q[np.arange(len(j)),j] + ct * p[np.arange(len(j)),j]), + q[:,k]) + cl[:,m-1] = np.where(equal_and_not2_mask, + cl[np.arange(len(m)),m-2] * cl[:,0] - sl[np.arange(len(m)),m-2] * sl[:,0], + cl[np.arange(len(m)),m-1]) + sl[:,m-1] = np.where(equal_and_not2_mask, + sl[np.arange(len(m)),m-2] * cl[:,0] + cl[np.arange(len(m)),m-2] * sl[:,0], + sl[np.arange(len(m)),m-1]) + + notequal_mask = (m != n) & valid_mask + gmm = np.where(notequal_mask, m**2, 0) + one = np.where(notequal_mask, np.sqrt(fn**2 - gmm), one) + + if np.any(notequal_mask): + two[notequal_mask] = np.sqrt(gn**2 - gmm) / one[notequal_mask] + three[notequal_mask] = (fn + gn) / one[notequal_mask] + + i = np.int32(np.where(notequal_mask, k - n, 0)) + j = np.where(notequal_mask, i - n + 1, j) + p[:,k] = np.where(notequal_mask, + three * ct * p[np.arange(len(i)),i] - two * p[np.arange(len(i)),j], + p[:,k]) + q[:,k] = np.where(notequal_mask, + three * (ct * q[np.arange(len(i)),i] - st * p[np.arange(len(i)),i]) - two * q[np.arange(len(j)),j], + q[:,k]) + + lm = np.int32(l-1) + one = (tc * gh_values_before[np.arange(len(lm)),lm]+ t * gh_values_after[np.arange(len(lm)),lm]) * rr + + noteuqal0_mask = m != 0 + two = np.where(noteuqal0_mask, + (tc *gh_values_before[np.arange(len(lm)),lm+1] + t * gh_values_after[np.arange(len(lm)),lm+1]) * rr, + two) + three = np.where(noteuqal0_mask, + one * cl[np.arange(len(lm)),m-1] + two * sl[np.arange(len(lm)),m-1], + three) + B_north += np.where(noteuqal0_mask, + np.squeeze(three * q[:,k]), + np.squeeze(one * q[:,k])) + B_vert -= np.where(noteuqal0_mask, + np.squeeze((fn + 1.0) * three * p[:,k]), + np.squeeze((fn + 1.0) * one * p[:,k])) + + less_mask = st-0 < 10e-8 + noteuqal0_and_less_mask = noteuqal0_mask & less_mask + noteuqal0_and_greater_mask = noteuqal0_mask & ~less_mask + if np.any(noteuqal0_and_less_mask): + B_east += np.where(noteuqal0_mask & less_mask, + np.squeeze((one * sl[np.arange(len(m)),m-1] - two * cl[np.arange(len(m)),m-1]) * q[:,k] * ct), + 0) + if np.any(noteuqal0_and_greater_mask): + B_east += np.where(noteuqal0_mask & ~less_mask, + (one * sl[np.arange(len(m)),m-1] - two * cl[np.arange(len(m)),m-1]) * fm * p[:,k] / st, + 0) + l += np.int32(np.where(noteuqal0_mask, 2, 1)) + m += 1 + + one = B_north + B_north = B_north*cd + B_vert*sd + B_vert = B_vert*cd - one*sd + B_total = np.sqrt(B_north**2 + B_east**2 + B_vert**2) + + return np.array([B_north, B_east, B_vert, B_total]) + + +def IGRF13_v(data_matrix, isv=0, itype=1): + """ + Vectorized wrapper function for the function IGRF13. + + Parameters + ---------- + data_matrix : numpy.ndarray + A 2D array where each row contains input data in the following columns: + - `[:,0]`: Latitude(s) in degrees. + - `[:,1]`: Longitude(s) in degrees. + - `[:,2]`: Altitude(s) in kilometers. + - `[:,3]`: Date(s) in a format supported by IGRF13 (e.g., float, str, int). + + isv : int, optional (default=0) + Type of values to compute: + - `0`: Main-field values. + - `1`: Secular variation values. + + itype : int, optional (default=1) + Coordinate system of the input: + - `1`: Geodetic (spheroid). + - `2`: Geocentric (sphere). + + Returns + ------- + numpy.ndarray + A 2D array of shape `(4, N)`, where: + - The first dimension (size 4) represents magnetic field components: + - `[0]`: `B_north` – North component (nT) if `isv = 0`, nT/year if `isv = 1`. + - `[1]`: `B_east` – East component (nT) if `isv = 0`, nT/year if `isv = 1`. + - `[2]`: `B_vert` – Vertical (downward) component (nT) if `isv = 0`, nT/year if `isv = 1`. + - `[3]`: `B_total` – Total intensity (nT) if `isv = 0`, nT/year if `isv = 1`. + - The second dimension (size N) corresponds to the number of input dates/points. + + Examples + ------- + >>> IGRF13_v([[30.0, 232.0, 35786, '20160708'], [40.0, 250.0, 40000, '20170809']]) + Output: + [[ 81.3243117 52.36266943] + [ 9.52994813 6.89129736] + [124.99133933 113.81947292] + [149.42321939 125.47594011]] + """ + data_matrix = np.array(data_matrix) + lat = data_matrix[:, 0].astype(float) + lon = data_matrix[:, 1].astype(float) + alt = data_matrix[:, 2].astype(float) + dates = data_matrix[:, 3] + + result = IGRF13(lat, lon, alt, dates, isv, itype) + return result + + +def datetime2yeardec(times): + times = pd.to_datetime(times) + year = times.year + start_of_year = pd.to_datetime(year.astype(str) + '-01-01') + next_year = start_of_year + pd.offsets.YearEnd() + year_fraction = (times - start_of_year) / (next_year - start_of_year) + return year + year_fraction + +# def datetime2yeardec(time: str | int | np.integer |datetime.datetime | datetime.date) -> float: +# """ +# Convert a datetime into a float. The integer part of the float should +# represent the year. +# Order should be preserved. If adate