From 0964204a2f44aa8dbfa40f9b2066672d145a9f9c Mon Sep 17 00:00:00 2001 From: 153957 <153957@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:15:54 +0000 Subject: [PATCH] deploy: 37fa23eadbb7dbe73c3cc18fc988477999377ec7 --- .buildinfo | 4 + .doctrees/api.doctree | Bin 0 -> 4406 bytes .doctrees/api_tutorial.doctree | Bin 0 -> 24283 bytes .doctrees/api_views.doctree | Bin 0 -> 57920 bytes .doctrees/data_access.doctree | Bin 0 -> 16280 bytes .doctrees/environment.pickle | Bin 0 -> 85099 bytes .doctrees/hisparc_maps.doctree | Bin 0 -> 18831 bytes .doctrees/index.doctree | Bin 0 -> 5045 bytes .doctrees/station_layout.doctree | Bin 0 -> 12819 bytes .doctrees/status_display.doctree | Bin 0 -> 3870 bytes .doctrees/status_display_views.doctree | Bin 0 -> 109880 bytes .nojekyll | 0 _images/coordinate_system.png | Bin 0 -> 21572 bytes _sources/api.rst.txt | 13 + _sources/api_tutorial.rst.txt | 179 +++++ _sources/api_views.rst.txt | 11 + _sources/data_access.rst.txt | 105 +++ _sources/hisparc_maps.rst.txt | 110 +++ _sources/index.rst.txt | 26 + _sources/station_layout.rst.txt | 63 ++ _sources/status_display.rst.txt | 13 + _sources/status_display_views.rst.txt | 11 + _static/basic.css | 925 +++++++++++++++++++++++++ _static/doctools.js | 156 +++++ _static/documentation_options.js | 13 + _static/favicon.ico | Bin 0 -> 4286 bytes _static/file.png | Bin 0 -> 286 bytes _static/header.png | Bin 0 -> 3210 bytes _static/hisparc_style.css | 87 +++ _static/language_data.js | 199 ++++++ _static/minus.png | Bin 0 -> 90 bytes _static/nature.css | 252 +++++++ _static/plus.png | Bin 0 -> 90 bytes _static/pygments.css | 75 ++ _static/searchtools.js | 620 +++++++++++++++++ _static/sphinx_highlight.js | 154 ++++ api.html | 145 ++++ api_tutorial.html | 286 ++++++++ api_views.html | 397 +++++++++++ data_access.html | 207 ++++++ genindex.html | 390 +++++++++++ hisparc_maps.html | 218 ++++++ index.html | 156 +++++ objects.inv | Bin 0 -> 987 bytes py-modindex.html | 121 ++++ search.html | 103 +++ searchindex.js | 1 + station_layout.html | 173 +++++ status_display.html | 191 +++++ status_display_views.html | 591 ++++++++++++++++ 50 files changed, 5995 insertions(+) create mode 100644 .buildinfo create mode 100644 .doctrees/api.doctree create mode 100644 .doctrees/api_tutorial.doctree create mode 100644 .doctrees/api_views.doctree create mode 100644 .doctrees/data_access.doctree create mode 100644 .doctrees/environment.pickle create mode 100644 .doctrees/hisparc_maps.doctree create mode 100644 .doctrees/index.doctree create mode 100644 .doctrees/station_layout.doctree create mode 100644 .doctrees/status_display.doctree create mode 100644 .doctrees/status_display_views.doctree create mode 100644 .nojekyll create mode 100644 _images/coordinate_system.png create mode 100644 _sources/api.rst.txt create mode 100644 _sources/api_tutorial.rst.txt create mode 100644 _sources/api_views.rst.txt create mode 100644 _sources/data_access.rst.txt create mode 100644 _sources/hisparc_maps.rst.txt create mode 100644 _sources/index.rst.txt create mode 100644 _sources/station_layout.rst.txt create mode 100644 _sources/status_display.rst.txt create mode 100644 _sources/status_display_views.rst.txt create mode 100644 _static/basic.css create mode 100644 _static/doctools.js create mode 100644 _static/documentation_options.js create mode 100644 _static/favicon.ico create mode 100644 _static/file.png create mode 100644 _static/header.png create mode 100644 _static/hisparc_style.css create mode 100644 _static/language_data.js create mode 100644 _static/minus.png create mode 100644 _static/nature.css create mode 100644 _static/plus.png create mode 100644 _static/pygments.css create mode 100644 _static/searchtools.js create mode 100644 _static/sphinx_highlight.js create mode 100644 api.html create mode 100644 api_tutorial.html create mode 100644 api_views.html create mode 100644 data_access.html create mode 100644 genindex.html create mode 100644 hisparc_maps.html create mode 100644 index.html create mode 100644 objects.inv create mode 100644 py-modindex.html create mode 100644 search.html create mode 100644 searchindex.js create mode 100644 station_layout.html create mode 100644 status_display.html create mode 100644 status_display_views.html diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 000000000..3285a1a2e --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 5fad2bde940bf7165069a46eaa5a9d17 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.doctrees/api.doctree b/.doctrees/api.doctree new file mode 100644 index 0000000000000000000000000000000000000000..8ad397cbd85ef6cb232ff5e15b43e03922a5ef6f GIT binary patch literal 4406 zcmcIoTW=h<6_zdSN~^2oi&E59Izf>}L89G0s3ZoJz_RZ``=u>Q4w|8M>;{>Tk9J2$G*3HNRV9Ep%ws(Il*_imTi zt<21@IlpdrVx=m&Vz;N34`XZJ_nr&u&&@vEq8NNcn8R9kr*#51^%Z2cGyLe(&P<9)9nW#xPpTpy!cW zE1A^Z-OW{6W&CGRd+8AOcz35JA1_fw|HOJ$i4Vl_f&rhsi2dAu5G^*r=raLbZ`O44fcbQ3|aimL%MmU{qKqs;~?oO(R)ER`AU)uCXamcl^N3J%HSLC(xYd%0CnRUTV)3`rdKVn44V zz{Yge*swCgkcmg)!2R@Fo8#xs{bbR(gb1Wmlkshpf#*K@HV&vu#({h58s{x&@yA6i zt`D(W3pswhMAwJyUApV zT%7@|Ee{<_lYRkiAxT(QIa-y)pGdV+x7kG?^#RDF>4E#hcZR2Hz`)-q(^kJR(*{qF zL8yr4VGDu<%KW~UZx;48vp+;;4;Jnlpy8>!R8^5Kl&_{zub?NW#A?3S)c!{m7x&$2 zDA5bm{KO4Fiq9lJH~#OQxoue_S(WmM%tE;r|730>XS0--R`}oi2Y={atPHId-ENwx zvA=YEA=4C{`O@t)0y@G*QRQPK9pb&>HbWyes>m+DyNL!r?=0kqf1t#XBevj(FVRDn zqU81(n~%>?)Jv{CTkKMF{&nlXM$S$(o=5sfJaRiQ_qfBL=N*=5Bbsk?2qvkUkh)q& zGiZk{x~$ov8r>`)K6H1jW`)T@ZHr6lHK@d47U)@JSysEG;Rzn9=)N0nH>osD8gVyQ zY`2tpzHl3cTZ^`Z(P_V%g(f;6Gxe_j8Otg}uq|`0k1|_U)}M$y1bxaeGcc>P$AW4y z3UFRxv89!=P!#}}d3R&v-BztajC)VPu-Pmtonf_uh{QCj&@NQzQ8+KWyFG!JLRr4B z`O59kj0QNwGphgomD{BbUdF&VO@0Of@7ENb@j!{sr4?~IFX6uCKr=v{xNXf#rEQ$? zGY)s&ben=@-LmKQ`3wUCwU^4YOg-02`M8?my4`c83wRM6nzI~~0Ya8=GKut)1$-7` zL{urbyc<+@a{QBHBk}!Uc{Ao(D;*0~q#2+I7{Io~dbd}5enCnvNb&CQ%FY!L;@@t! z7CKj;J^EmIjtx;vUDN~bZ>n`0&{5*qSO zTpu&S1UAAQGHuZy`fit1R>gCYyD5RSowUl!xWgm78VHi+se)xBa4%3oHc;s2q|)#z zRq-q*G~ME}QW=gRZ+xWsTxWekBKX({5pg@V*ApWSf#lx%=aF$D@UnM><`d+R;7TkYV7yqMH zJoRM4>nYbm$?YWEK_kDgd4|gdXxT`i6s7ywhC2ix^SH~*&VU$m9T0NqZkY>=hO=16 zsmSmHc-JyTxZgH8LzexyLP{Gr>P}eK%Q#aBtGk6eOax}`1mUZb4PFi|#Oc$j#1-^z z3q7Ez0caSY&_LJ~h1*mmOf|m3CUe4WrdXYc^v*iTiuApJ27+VQxpemuaGl0H zXEKZN!la@bwBB#th`?$#sSDbrTjj+Wz1Q4ET}qI619H8fedMrZb4HJJ^nynCu045B)%43i8Em;Hz2CLD4{03!M?r}XRj*p z4t;-x2cHqScqFoR*1y{5A9W*HH+S`c|0QTg|Kl VR8Q%j0h=jRsnrAhz* literal 0 HcmV?d00001 diff --git a/.doctrees/api_tutorial.doctree b/.doctrees/api_tutorial.doctree new file mode 100644 index 0000000000000000000000000000000000000000..a0f1f2fa8394d5eff89920038ec9d2dd82cd75e0 GIT binary patch literal 24283 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 sCi_yy4BK*<3bx-tvInMAu@rap4E{ue-$L literal 0 HcmV?d00001 diff --git a/.doctrees/api_views.doctree b/.doctrees/api_views.doctree new file mode 100644 index 0000000000000000000000000000000000000000..0dc451d6bd01a31115557ca112b6f000d632d669 GIT binary patch literal 57920 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 literal 0 HcmV?d00001 diff --git a/.doctrees/data_access.doctree b/.doctrees/data_access.doctree new file mode 100644 index 0000000000000000000000000000000000000000..bdf03a6dc917aff662c0440f5a7b531a4386dc7d GIT binary patch literal 16280 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 literal 0 HcmV?d00001 diff --git a/.doctrees/hisparc_maps.doctree b/.doctrees/hisparc_maps.doctree new file mode 100644 index 0000000000000000000000000000000000000000..40276d9ab0b834f069b747b5b0aa42a0206a6166 GIT binary patch literal 18831 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 KOO9(+EB_A!a2coo literal 0 HcmV?d00001 diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree new file mode 100644 index 0000000000000000000000000000000000000000..3b6d40b2b77215f93ce4ccfafee18a708786ce10 GIT binary patch literal 5045 zcmc&&TW=&s753Vmv1e?LFPk+%UN5skAr55hMB)Lh!~RXyI_Eo= zs-L$$`~3ET`?H%m7c!k3vM5Tki0jg>Mp;-SJT>K~`z5W!!sYk)gj9Md|Hq|Qx}7tqXiBkdJ3%e86ic>U9p%I>$1>&RNik%$%ZyQS zSQwaqj=UrzjpNysFlJhVi0@X)692Ut75Qv1WZ{|OBjPFSieY1#D#fPQ6YJuxSQ7j8 z?IV#T{74mP%GJ?%rp}IXckF05`+$;1GL87;P-*CW?|88o;^ZA1gpC!;Mbm6Qdr$EG z_vH^CedpbW{dp5g-8Yz)so`qGLXMHjim~XQ3mJ+&f5O#8mhyhc(mo4Au639ABe86Bb^seFRG%dbEp{?L5q2xzy+f^(h;a*?!;t;`^;M_Uj;!vLw%n zG-^23hl*GLkh0Jy-i(!M?nMU^d$#591K2`)B^_7~PV5>vHt>!ve^H*;b(YJ(6ed%W z#hxOh2F}7DVYzmcUIl<4W*1pu9Bm2fW|M^uBCNtZXxy&LG>nUgk7VpO7C#k_#ZW|I zBm}ps37bSbH=;aVL|C!h

1fIL?OUrELotMaU_acB2wBC9I}JGUSR!R&wp5%C#Ms`ki?k*v-nSgL4E_&Q;0gp>bTh$jbqg_!LTZ-$(6$3`)sr zP$w1_91vDv&EE5jE~K89)mRgaU2M7J!Q@a$alclhvCf@aHNo!uAdMt~)`cqcAalDc zx%=Fy8DM{TbHGya`lzAO9hZvMhD9866U4{|&tR6)dxvHMX?W6@wwn)-9v?g&^VGrf zvDbDQZ{l}O`vtq6bDS(42NUo&1XK(i+m@+I*>zFqxL(Z*~PEbCIKHE|F-vhW~t$ zqu5CU=+g8#Q)&5$TW6RWbA#$SJqV%s4;7lf1T}ttof^%oM$Er`8S}3jl7B^pf`@-I z#aQLCB!fRtk)CncKb_0|Sn~@%{>$7LZmA_S-147m+#>#ZBai(1y3@VLBmcd*N5tP7 znm7IMDop#Y>o#xtftdgCGUnP3#QdxudOmbCM{X96yK|9aH?BI6qDO zG9&Gx4{}0hjyc^Xe%G)(uZAAn%r~b!NV)FNFL2N49@c#!57h@~`sd4H@3i|81)44* z{`L*{YcGMn_R_2@)LFmI>9+0jWNB}G-L)H^HDb+W)hk712O&oJe1O(#Q04PkC8=kd z+5Xz`ApY^=}-y6(4SGK0pzRojZk72kqPcgyy|LQ!uW zOgriIn&LZZyQ;Y{$mF7dkdv?584!J5i4169#uOkmt2kph=_akcPlLPvJ3ll;B(%5!5#X>{l(Q zt_z9+d~Ghmgxz0!jxi z3ppK$^ph!U7VtErEIlr5r!b?zw+33``|j1rfGd@$KmcMfx*h~S&K9EFYo|-? zaQK!HsHxb3x^cF<^o30{SJWiKHzX~B%h%BEPKU?0>^8+4kdux9#8@V1EZ*6A-S%>x z2h?pKN|9KgIa;e6Xov0;8unFTOs*ds9f7P5^9v)g^e|InMARMPbP9koKqm+H7`S5< z^ucRyeG~TVsZls5o+vZ%U#rDapG=TF4@@S( zG&rXR2yit4LN4u=zDNz51VWBQj34m39A^amb)7H-+WQ5fTEkGc-PjLa!xp7WACqZWvV>z;y%^nT~*gDlhC%qR_=~j!haen%cYNYMZ9JRErOo*qKZt}7a_vx3I%J; z=MT`N5W*Z4UQdQuJOzd$zA{Iga(Avs?9{uuMLSpIBkw9xB8u+J%c^E@*+eP{aYF}Q zP;0^rw;%Vmg<`Vuu%dqot9@L)i?F~28UcnkA`K+?4W}993VCfxcFtU@F1!HGm>!zC N5hcAUKls-C@PAykj_3dY literal 0 HcmV?d00001 diff --git a/.doctrees/station_layout.doctree b/.doctrees/station_layout.doctree new file mode 100644 index 0000000000000000000000000000000000000000..7ac2fa23e0f521866d5b794ea6ec01bb0d509e05 GIT binary patch literal 12819 zcmeHOON<;x8TNX;uUUKJwUZ52V$y*)UI))Cd7)(U5SE>noUE)QL=j48_jK1x^=v}aX?%U2_VGdkZ=kh}HKa zNFpL-cBYxP+iB)!D2yZ9V;w*8>1#C} zpAsK#wXEm4pZ1-^ecnn~KX6>Ox@tY_KXLBVri6o}c zkwoPC)3zfTPL?HpJI^3L$vf$LDP$8fZs4RT3h{j^azgcOrkuBMu-3d^mCv>vcRgVp zYMzUk%;{29!5d;)Fa7}5x+0g?@*}qp`vN~=#n}nI#3#j^U1^R_=50Q&w1?F$(Q2K( zZ?5#zxkuD07sVufR|~^HC$J)ZEtbKLKnK_1|DzCp65R`jTlo1Ah{tc@4StN@%#WYl zOOx~EktuJaDO0D9-A$M|?-QraoqO1S{DFp^eO8y$BHT4rgjqe@csV8wIp)Mn%G{An z=hL*S%h=W_pd(-=9+t}ewbIO?ZdTxI#yR$vaIh%0t5!-|#>{J^0e)`?4>&0;=wH)iAb5B@Klrc<=zn;bXjI+eL&59H24l8y22v!w1 zS)4RHmO-6ylD4cTfnM1afAW-hRu)@SorHj*g%K>a;kcO<#IDk0+@aD&Id{u?I3BPI zEIBFLk_;Fq?m!GHiZjc}WVs9Df-I`9-jtJ#Fiu!3JIl5~psTQ+gh6nh`avd$k-~Va zfwOs1E{;k(A3{VfOB-#L4H#zB>#{;;6V;s#OIp^0SbxIYI7+i5mmtz|gv?3v1mk;7 z=2(8#fareMj}r_FxnpZRiU)FXbM=fiLC-|XMz0c`4YmR1@uSq@V>(KiwdO6?iL5rW zDjBe44L1(MJo2GwwGnyRl8{{nW~b!lmqtYpwM~ek!3d{~Y4Y@6fg!D8>;I_v0Hda6 zvLTqTEhmA=WY6LVcm^~ytr-n;^sqj4G~GU?3&i2maoER!Xt{Bmczy)brkY{L*4097 znAqKVJefifz2>U96mAhheWsEje-cDc&u^uhX~sfpzyR+HsNr!6Ug&@V;EcF9)cvR{ zExI44(u)8W)O1MP1&++Y6w(C!NVe_7K@bn9XUFe?FqBck(CH2xop9%J5Wg{p7$zpMj}!-I75;Mt z>e;}Fx;dE;pC(wofo*#YmbEDEyE66G;2B!g?g;!kNb$?J^ILyjS`angf|Dqz+ zOKS*~Bp{ri&mA~j-GEi#dGi&ZXTW`ULZD0u8@Nd8&4Hi7Y0Q&|$WnHxe6uyURlN4y zNzb15HUvcin#Z~cV`Gr^9+QlKxinr`2Cm*Ram9aKsku?Y5en6K-23J$M#q1e z9ftwQfB*Jad`n`{fA==4#_iCOcZb`ffa2eFi(6{E6}P`TWpU2?0Kf_8*1@AdgCYrrPy-&jiZlrFb-+dDA)}Pql{iUZmm0eY z7F1MYgheu@QR23&PxT=}L-{3eU3Mbd5AGt#ni};M)`rkKg4o5h1;dCmr$1NO(8O~_ z&l^X2UbYpmrXS1Zfh`{t`g-$zIKUcPD4?9w!YcM}T6 z5=NK5J1hDqtmu=MVMS=Kt!VoR#Iy<%3Ng`?ce+0@Ts#>=LsK<;e@H0!=FIb#_aDtWcU1$}3I9VIfrYYd!V9YGp-!V&B_<4K%%xoq1{VqCw|eSdk6t#8-# z%Y=H~07aa^1-?4$Q{0ee8G^eQ7v9@4LM_D#jDMx$)hqh|p5aC}VB5aQdQFoCwv3DG=C^^9^-+AxDu{QWoeAP6j z8P_Bx?Zn(+7=GTa`-tmGdjb_TVGzwBDym7`XeRAuq}dKsNc^$`6&^a}l9!{Ikdg%| zkdLXV_0YtgULNt?QuUC;caKSY;%CGy)g6g(4rmH=q?`r=t|HJ{JrA<5?nSL{6|N7cMg-;7-co&{-#CIOJ9` z3LD*qhmG+KkeUY`b)|b%-|n zNM>8Yk+T2#P2p#YV#T0@0t>Jq7jl_o6!)B98%^1 zv`7|_W?ZvJT`S3>tlfb$V4Jl-VyTP+wWHZAH>{pOx6qDeX&YOeG?{!?ZUqv;>Pbdd zUF8w-XT;UWScp=(zC?~B!ZN&_r7C%GD#I;nP@F{ws@pJxpnGz1wkE`an;@`W>Y5JK;&{R0%9sR6VG*&Y6i4VKjj2DUgxzPiD}#)^^t40#vff1b6ti^ zI7&Jz@B><9Ky=v0kNG5yGl+_O&JA2xtrTKjiGWA$XdMk2<f*l}H-K-E- zDa{+BOvzCSadf0+WQg7mh)NdJxU~$r_w~aSBb~)TS_80`@-p$Z5C`IK zawAJ{TG4=4$r1^6+WoqypR(MG?TwHCbr39xJ#h^gB~cG*&RQ?;*e;&MBgw;$`WatETYjoZ23HnOl+0rQ5QfAe1svzV+W6mg+A-sMC$SZk`{wQuMf0Cb}|j|A?^O67+0m68IPk@oOEGP z*HB9-09x8e4xzgjY{x9ho5wzW2lTm+blj2QsiYo$$h#)Ut|O_^XIV$i0YX^eSr}ll zxy)(9ijWXgoShX%fyvOWjI&yRjT~*{eP0p>)6FPzHf)Z^+JGKxDg7BwGlkfnh7Jtv zvpK9fg`y72-|DALnV6+&kGdR*vMx4W*&DPhRfyi}c^^|yD!EJzE@|Kr&=VsMwgU{5 zyl{w!0{-PlGntfxxg2GTl$X6;05V~ld9dJ3NI-XHnBy83t=4V0L4IH(>z#O4O1)U- zgaWHUM{(LEG0CC}1u}}otYQMcXWH{ZBT~$3vgYiP<>zSy$Dk1eV#u4 zgm9_%2m1IHeSDKXeoG&3(8qCVaua=AO&^Q&u}L2n@R5r-8k1ZUxdJ)rB{||HIod@z z(nUGSB{{-H+51w?k6B>M&J+G&hZa^*$m>`s^JOJNF zos>|6Dj}}X?Ueq_5;7233ebk_IH+(f3$Gq2tXj_vjX0-gm7NX^jgMm^$#5?$t{EMx ztikCGCUoPRcn(LUis(B4H4*@JMbU!|4P1|*FF#>@gX6w;B-xObyf9OU)6lq`}^IKo$Ak@n39WP zIiXorsEnE54>FayoE0|w6yEhRIi0fLcc77SAv4X2@G|)0sBVQclV<Zo)uQIwO9V(Uo5rGjQ=1^De3k23pQskjicfoY`Ogp{$N7Cr7x7i#C;SmV;*a?rKljh3T;*)4T~RPSy;AyeTDnAv zG)qlUn2AO$xj}vw=GP0l!#_Q2sX&wkEg2oDw1m zVF{U(*Uyjz1Fwt4Sk2$)B!7Zi10DvrWV+C_RBm2XB1cAO}Hx zR$tq!I)=V6!7&HF4|J#?GZFw;+wR$B`UE?d3lyrdy%c&hV zS3Wi_&uP517=K1B9p{W1r&%^kuE+7R5Sf{@!Tb+TSmoo-zdj#(|1uwg&sAZ8O7pDs ze@(JF@8z#M??dE&uy)=6tfcZ%xguMGMN=(1C{dMK&DNRcKU5NbAOC?rkPIy=mINg&q)Nh#?{kr5 zAk`Z`Y7BIOgTmzrXfX>fcKop7P@@WY4c#HQc~$cfo+aQJ({qUQot(BHF~7DiT;K~P=`%}h<>J*zC0b)p)bDsL{Hx9g8nr(=^KT}wD> zC3S1?2ZmV-GD0sr?V8(MS18Vc@BfubhkNb1V_!L2IvZyEWabA82D+zK>3{`lnITzu ziN&E-%EDE^Vj2AIH2A~X1%h)gp)hQgPD`vtxF-_ZOneJhdhwF4gFlXr zV$%gk$a1c99$rW6YEcr@L~P{-1|QWDCRrsRSHg1AwmO{GY-oDl%pYl1Ds72muNcyK z%MUq~-LmIT*%JKS6hWiZ^Sz8EZh_;Duc$7NMQCV7b4UibvXsS;qJN@5&IlU4%Aghe zz}fl5Cl^NG`SIpU!n9VJa9U&%fCUT?TWW(psWZQ3rB_)A{(S4rmI?lgKdz0g9B8*b z-h8pO)8B~!0CmQgM>O4G z%TgJJp1ayvK_s;xE+cBZo1hG z>m}0@!R)*`BTj4F<`RbuEKN{C83_HwfjKQd_jmVE6{(gumTTdnIQkt(Hi5Ao+I$J~?R`s#{Ama7zE_oXXwL>$Dc&d_iG z+6W|~m;(b1DV#-?FfQ3r6M4k0RJ5+dI3iyLKn5)*L-}6A1J0Pm8TV6YT@sd4AqhSi zBI#CMpEg53uqx*@q22gBR=kR%wm+z;1hoq!VxkqO4NEN53kGV!)Orf1fGmp-37`g@ zGg7%f+mP17H^i_u?-u>Yrg6&a}1LG z+JTP9+wYXF*YW4H?PqPz!a!~?D~H!;CSMJAcXlx7|G&rJ^|{me(K_m?Jd9FNPmB@i zwIq^Dt5+v{T~h1e8i3L~QL+ParFw5m*l7G+Me#VAG41x9Z+ImcDD@f`tq4U$C~_^sDtlqoqov-l%x(Ua+FlD0e5l zdZ%}9Z~L9S+j_&nK&y1H-RQQ;UN2YxCCYxaR%vdf=;g!kRi%s%2TPizYO5EVI@zdn zYu<$g!Nq8};ZfRfFF1vj+vzUmFWcAYmAd}v{!Z2Beg0;UtUt#RTI#vFxgb~q zlcyXRmSGsNHF&4ku7X~4x~-7%??`HNc*lCK~09^^sv*65E zU$nIY6J>W{8x_m8OGXM8iRO##W~uD$F32KNAF|cE`L>Nxe`oaA>l&oAv`>sM+$` zUh9C@L)zpEVmRt1dGIXe)q1&FL8qcnDRoMP zW@&=E7ehhX;%eOgDt_GcS%f`%20VcI2}vO8zvQC+zA)6m*q%lmfUjGIc{f_vQ>xXx z3fk9>?-gEt?KLnK;};gnr8-Eo-YLNi->WrYvHs`#kBaFu8%?PpdoI(E`9A`%TdYYamn-966BZjb56NL(=%$eZul{D{6RrKFyCyZg>mXp?h}eCRu$KYjNtMlsYdD?-hs~5 zNI{q@;bz??>s%L=AFfD-g6IvYX=DSeuHuz#*gx#QH3YB%^TF1VHInxKjWMAP!8@hA z)*2F}Q+?Qfmn^W97U0?Mm)Q%YQHPY0Q@S%tg2}Yfq3PfN%J|Zh$f}<=z zhy9_NIM3b0XCh623Fl2{rqoz=i4g@WPEKa*C=rCcqhVi3A%q!XT5#})*aEuHX^a-GHtls`yw#W#)*ig14*2)=!O2pm>=!0H2w=dn6Bb42 z4#o z!y|)80s0Ap@0+{rkY-l+>d|Km7V@~y|I&pj}8aR>);P#BNdi^lHK7v;qRl)cw!9~7k7Px@iG3hUUbzT}r(9(qA z@bQ==59>I*sjUp6EHy@=Qa1?bnb8Oo`6i5n?ne1#*^WKpM4mP%jQQ7y*m4Lt(Pqp^ zr)#9JbPsj#>!*k;?TgC&U!x)xPUhDC(V<)^IM+t?3|15iJLqWG6t0YDK39Df& zDn~Kw1ZfUp_(m%4Xwjmuq8P(&_l|xET!p+u;SR-mN9)|p*u5jxOc=my+J&Cte^HhU z?lq%jl1G-MrcY*gp6Fg=k2N&4?GL~hL8^akH z_LVm>8VSwNaLjn4RluN3t5Yp^Yo%5JA4y<*n-51;GNr}mxQ9)XuZY&nv#AZDJ(KqV z6jn)cHo_-d`m@oL8nG8-9Wk;8DQLV#7ggSn%{k_xUxjQe@T+1qFU)D8BXNna&6Zt) zIL-U!jn%O*ofM$CFxD(ZDmy}v8Q-Z{Zi`ltwDWuvj%-Ng^->Hrr@*%x+gpJsWNe)w znYX)}up3&|gff5TlW^h2p`ks<*y$@I^C35rb~${<ZG^@d-#Dli=LEoe1x__T3xn2`*KqyjLarJ>UkIF;8uO!@uggV?{T?`wRgNzECMjEK?)Xt`HmbEHyH+C!~jBcg4K{I0K?)9 z{|4=`c*9RIMdJ-Ll_%c7tbHsu`q}}zj(rf0w-8o%G7kqdfD|7tS-4oRzX(&5eVWR{ zK5Tm8F|*v^lFP#TeO}-9G2KU9q?p!j6~Nz?B><*%DXbY{g18!pLQdm25RA zjHzOem0&YzVbgv$5u$ljZ%Ly!*mX#E+v0$jmSNfDyc1 zjbPp&!`T>QpifW^b&41Q!yrQ(7^xV;-h76Qdd+%kVM`}F1R;j^&KIz@@SGH3I4e$o zk-8#=Sw+w3){d~Ov^^i88_ERyu2ZSqCg1@{JHLf*1Qx=P`u;-rpO+%ASTja}tX5H5O7FU=4x7F^bo&82B~V~nR$+@G-Dcp? zeTlFau~4a&J94i_h7#w+QY2REW;Z(*01;R>wL5U(#i9*JsmiZ*S8fkP^U4Q;Wz{-8 z2dAChSc1wUnqq&b)?V#wEr6pG<0UwgP&`nob-nQUhv2Aox7lp8I>k1e0OS?72ET#Jgp*fe0)u$!3 zuBWD`ShK65k08{Ou)9fi_0+u{GpY<7=zcxe-^aG~@$-mk<9^E0N^9=oJfydwn~{Rq z&^O8s#E-VHp`x>3Ls<pxCxYpWL-fcoZDQSawD`dln zF5>cXo>#+J3P;k2>K}O=yJ~{*qmVfRVC=?BG0+IdPeX$)I1Udo1?1FPgq_B1+oGq? z|Bv(WjXpKhcS>EN?c09MOVP8t&g;Aept;m39IV!Ag)y(tZNpA$SoqW$js1mg6K;BZ zLBy6m!*En(rB;vTH~fGzArur2)2*fF^Wn6TIDW5r1%rwOq53NXQ(CP*G-`E1Hu*;^ zy^$a*Ad8`3d-~p~nPzq*-haTMfa7@NW7sS+F3)g&p?S5l>d?zzyE>1#6(Ch+r{Kn> zsC>DLQ>achYaYHTfo@d8W5UY427HENZ?J8CssJaoain-1RihNt-Z9-pju@|e2?ZScOV~;lYr!Jz#hUNrhnhRGv|^ab^%h3hg41$G z>D*aPopT$_U6OY8_h)616g76f+B3iW)!P6!wux6UByMuQQufojn6y8*y&Q-@j~4_- z%d_syZoS;;MqVNjv&wvhv(;c>GrZOVq$Mvyl8uBno!BqW*@Exv*H9p(sFVpC)&VRY ziNv!-+~Tj)h+Kvhn7+vl$eaP+B-7-YCU1mRT@H$6R=owcYQG8SgaabF1Dzbfp4r!g zac`2rS`e)TsW1y+sq)Px0}{)^2bS1=nI5#x!1`U7qF_x^eSkHGv%F8^&Zw6T6v0G$ z^-8IAWEWR@OR?xYkNo~HzxfwedOfzqm407%n5#mWYHEL!>#tD4uy5kF6OTyR`77jp z7FVi&ac$erY0Mx^Le8Jqs zZ^_)Ur{%%Br3xi@Nl3lpqjyfHJ}j)@FNlclmj}kv6jhq}G;iImnR!NEulYG>j{)(IF-3uxruqP4#Z7Lnc@zhkj!Qco6z6?fq}quG z;`#FoL+3ULhTXGM$Tkw;8r0ih{<@x})O=tWb0F+$?grqcl6D?FAksU|JalzdF;i?y z^^P2i9W~+iS1{9N0Dj{iH0V8xoicnchO@f}qd zGGVG{f!*YSN*kXiHOjgq(sl+4&|S!f2G|~zY$t=R=pukFt04#Iz7X1DpnDajDCp8u zKcFkQ$ql;jI=BPHDX-K@iMh|u`D{Tp6A!t+F>f9$Xv`)d?kTY`09lE}>m86ch0Cku zC%%?5fU@*J3|Sw7mf`X8>(u_xDp*h0Yp$jPM3%%>}mF*ix)b zr!xX-MF#=1ZscR?gxXC8)WQoh4^$iQvR%$Ev+oI|ln%a)w`tcw(?!KF`>T15K|OnX{sNPW&PUSn<+qj>e7()G~6ob_dvWHNg0HW>~c{%u{>isJAtwzr{>nA1Z z+J?O?5d~(gB)`JtpPWs^M1gtbLqQgqD$PUk?15sXbL6X7foXa^0hu#kdQ#86X)>_f zZGMcYhbD*&0*x>*q8ngfKE*|1F)&F1VnHhAagG4-3BVLX?~RzE=uK07pf{TlVP;ID zg>e;eILFC;{9(#r$@+H5I!)zaeFhFw?&e3RbDg4;Z>P7u?{_p(b=b(HKR&rJQd8u3 zhQiI6e9Jkx90p0B`pE$GB7?&4XY3e@&7?gyd5LTwxO28`S!5id2PW5B$}msTaz|lo zQTEDan%vf1Nrc>t)i6t{;xjXO5T)znGv*-5Yk>%mQoV6B@rdLb-Obo{1hZ!1Axu2R z#8+HQQkD$m)J(H+5XCBD)e^Y?s_Vm;(Ib*2?DI7FAp8(a(<73Y5cWq5F0g+gmbE^h z)OSeze|tpoVcvaVgyP4M2ejr3RKU=ENDW=yr?ES6Bb9!_2ppAu2DZ=hk6(9ctQ+6IB5CKTxQz(aOxm0OE&Fb>i!t`* z2SAj~-u$b(8N0n<%_uA2I{5fK%2GT|8TLjEIr%QKW-gw-2$_A@8){$R<<47@Cj!Rp zHmrb!lf`|BJL-5!a<$sCY0*Kz#>e?ESe8|4_i5&{iu@FRW;*4aZ3F@6ZgBiKa(hF* z#77M}bsQ&leXRt^aCIdF0I@w*Lyp+qnb00v9iD|Lx;mt(JWDKw^%^(1AE4kaK7P0^ z!CdWj2lVX9C64XsU)$0RRWRpk1?`Y0EE_OPx=#d@q91EG-POxsu{XcpbBr%`>b2V{ zT_tIQ`6gS#9$AhkYNzoncQYSgtVmf{t(4t-yatFs2@(%5w%nE54=}RI$*W-dzEHBj zd2sO#XDehJDhjQO;~vPI0rPmGYZ9Vi`~b9L zHH?w-iJM(jX~s}=2W-KW*fZ-IPdkc{@~9yXonZPd%47OO-SMlmcgzpt zrx;B#e+Bz=5fxZ=3WSfKaeWVGDz*L|*G#)wyY1e$C2cVO#A;Z+Ogpnw$H)({k0z)- z37Inhsxe3?h8AJ<=g^WBR>R{-_Xs3w3PKDXFch5vWSZt<7+q)R;j<%rz;MX`!*`*C zG<_ID(w z5)n03eViHeWe2V6H~T}&3J|5-7;?Z_zjI>zkZS#B2=Vm0OPo;ypd)6%Q=p zx!UyrE=pBM87nZIh-)Bo2Aqg=GiRDS0L@uF3Cmoe`#nAg1j1nu9e{4_!@k(pVoCcw z1gS9dVL7Hc5cmmbouTa~F-6gqruslzj!tGv#3!WBj3Y5nt1f5kU0Z*WLeaN zhi;nu2wJj2QFuJ#7BzZxTD(Yf3NY%=_!vePHJYoP=CmGnC(;yE+V?Zwx?TIson*NE z`EjIx@c`EUO|l+VT9XXjSJ6#bLk{hCRD(?@*_49)2HXLMe_{`?H z%FkYBeng^bjtA6v5XRTpOoG#xIVa?o|M1>0=!EY1gmuylq^C&Q`S4UEB+hMtw|C@T94Jz*BOQ8$3@#O_2xmBFjd# z8|s3rF?LyTJaoQo?gQ)^mr2OEDIy(pPRrtjYR9s;ZfiM8iQmBW(5}R8*t}iR2J=jm z{h+4m6}bmHXrksJ$eaPxjBXEC!%3e~LNiv-)P|9|oe6p&AXD@OAoEr}ZcfNdI6}vD zDxs9pvk&t&?RsXS9(tO$AO!=@=}A$bGO9L$qs9>)u3AQ}Ql;;5ZLq778?v63w81;) z9{mlmP^8fUqFcW}87uvTvwml+l(mu^D;-=3cmUBn z`>@BvN_pi&K^j>q6+<$;t#J5HM=L#ys+5a7ixrrb<4MSz0n3p*zu*lSAS|o(FlH4E zpKgc3!b}Lp!Av~GgPf( zCO?25f@wS+7#tm)tJ=c>!3(JNtB^Y11582cG+`^o@pZY?M&0&8(;p+xA6y8RpJ0j_ zV49jED|RtIKQ~^TD7G8jR@uWRnCXpJ!nyBA?Rjk&Ju(63{4_p=-(K%dj(M$-LT9RJ z`H<0i3k&=Za`cXxRs*Z@8?2?0cJ|L&M*GBOps(!J(Kf+RhpLxGvC z1X_?n$zZWg1fsMS>o{6g>%kIK2$OFub0}bcC?3zx!{gbRc}$I^N|DI1$eM|z3m~&! zEM18ePm}B6hhUmw=}{3i(x6nZ0#LdLiLFqoZyw#b7rq$8=5DvezJP#VF)fTYTJToY zcGD|Y$E)Q6S2#9eLqSF=HHtTLrUXcbeNA&^0zt9)GD|_AuT}yb2nNTiUaeBZ_aFAu z=QYFusexcAy>Gq6N$aIaPrDxszNFNGtd7@`@2u6clnke`$dDYw(i=$!e>V9epr(**;ARxAb19+!cg@8_!Ty2@XJd9L@ojZjpQ4KrjSIa(r z_ylyifFC`HYNGf6%7S1`4O(lJYQ=V^)u>Ns%|@V&2h`#b@4iejd>@nHyWt09Hxw)_ z{LLNr7PQZ$;2nJl1!d0QJx||HHNs|f@t}n3_h(>u@1?9cXA}8#){A%0qU1N=M;y80 zqppT+Kf*H(7LEx`!#h5sW5Y*owD2-0Hr}Y!8V9TOiNR9KEAVf`d6nIT1C3gzG~taD z%H38AzOyn?m}tU^w$rLkOn5CmzU2KHKOFq|D4LewOW2S2u$cCC43G}tWA_;CwQcP1 zj$R#NHwY@?$@_XjR`ep#@tCn!;Hcw zu~YCUsdJ5XE_9l$(aysZU8B*|9IeqVL2nE_Ciq-yu0>ixq%m53-c=es*KKeLe*!Ke zz>f&KTx3f&OMKDB3R|shu-sCb{Sv2UyW@-3NZQ$tFIqYkS+AWCFTu#FZ3&i*ta(%> zta<1kN^%pj_Zik@Wgv3Ff*wgM(z1Q6%U+*{$6Nd1(e&!5o1kK}*4wVt?|bs};NHwV zh(|{wN~d(5+>ET5E6cr*+3(8oTC8}Qd>VcTrdgCOs`1*=Qt$%6e-%=vTUwS1pwkGB z=86(k9Y3xoa3{31Oi!gI%jY>$!nQcQBRrTkZx96}`dKMaQja(&!^zH*zEb3Fv!11- z^kfz(iN)hLk;vsjk+)lzcCIi+>G<;%22EqcA+jFi%41(7Aem4b6FPsCsh@n2@GKD7 z7kGF__dH>da2hTWQgE(hZ&nhI2x3|H_mm;0CW~d=-_oM)W!qgyrLAnTvY^5ZT3zcMNfdmZDak6*ne%vY^*eR@_|k^>Z3QpC1i- zptgvR0En7vI#Zz%d|9*xAr1a%?&0uaII}^!)R3OLTYNAsj2#TTV+;n>{S>`XLt<8v zJS6959TI1iVvYNQ6f=r1nh^C;E}Fi^Cf`h~aSs^Mb`Kt3DVCJ}lVROvB>V3%-^W23U9xP9nON z6;6GYfi6Q}qu8lVLg1s=7#|1kjebog{gcOp zz3Yy4@~&=Achor?M&szxcB6w>SUhJLrTSlmk<`I5Jbm4Z-Nz;E?C&mjO2FJzW3@9KBj+P)CX$~Fnf)U92v$5zrr?KQnj-lr$vUP1y5J1}eJj?M56}f^en7t)`#=Hx zFs3M=)6^UR`qd~!h*#7*;H-K@`b2I5Hc@ae&*-!!93M((t1l>b^&t%36wX_K>hPW8 zs3Ut)B9rWaO=39(IuCG#6IzqSp}k+y&i>h>L`j$kenPyUBOpH0xcEm>P#KW@Q$Um! z**{LpYRJA6dfV!lMo7HM(YdT@q(i13K_ph82 z;e&;jYWmDz`wKRa(~$y%3f=gz?1q~RPm7B#!y89f4RLQAac<=tST7vDK}^wT0!`(0 z_!Kj_-_CRnj{A6{+|3v}*p}?+(OT{99W$Y>S1_Ne_$oKL^-gPwyG`XPLj02)LeM2T+Zh5{`3rTi#STFbmEBZUe50dk;=c7 zKzB=_WN??x1tQoVlW4zR=&syuI9TNw496>+t>iHrj0LwbK%~Mm?`JYusE3TJbVaue z37Z#cNci7sNE*)m#MtuvjE%%0xy@ad}zVPT|+Nc{v^r4gxr!4!2+ zXezIR!tH$C_wHVV!h*ANwMLnq)XnIlj3)aidgXRkCAecQY;AilZu?^>|s6{v*0!4ye32Te&a0bt3 zGZ3W>6rGTwtOj*z0LbyknhA9aA+ukoTa6V@lgr_UV46Z5JtUUjQJbdnqBieNKku=m&l1eX)7f6;lHyr{*?=9vlNXzG z5o}gAj7J^pX9elvGm5P=G;dZT@YQ}(Dcuy;8@tlE_fd8w?cBueqkT3PqbDT@lY7nz zfU}<+yhjQl1MUVuloogIre(DNz4rPRWg)c8=sR5=&cow_{qT4c#Mjs*Fc!jIw;qGkqw`Fc++{Tzt|mBn z3-WE+@FryTYr}8Fil@nc!waGG2wXxnIOdloPBsH?~y$hd0ZAbiF1+1Ad&0XP4;t<=iqRQ zH?PpN^;~3FW$fqmbj2}`N1m0byZngQE+Dd>*TXw{ycmv0?sOlIG&`U))~qWY6`01t z;|R)^)4vp_B)8L|?o*OGY^Nj@zkQvPywMPpn`tih>nYQ=ch}$@L+)Ep?z9K+%AOdm zm9WhUl7;kTiJEVBW7*aBe z5>cvQGLozsw`WxiXO-f_=4mNvxZ@`L`0(=b$Qm#M}zN zPi+1X61hx=c4Bj<`P zpWYO1g79*jMD+BgaL?=%X`;hFgPyQB!@pyS#u;cTZ=9je=xsu?1!;amau@PWA2YrMQ`C^q)EpTS`WgUvNhJI zC@IgRY5BAiOa{~P2_Q;qT0Tn49zoOc%{)DLqMsgQf12m@*C~IL+U$ z^6>cc%si$xe`?B-N0Bwt{JjS<`!#v*Vtx4xp&%9L7M4?*71by*PYvNNOi@EfQ*&epuL`*lGM1KWQFUR4MU~l--53UM zpVPHPl*y!RIhVV|nZj;Ft#eqzqdc+W&IzTIg}w^(E*WHu`#6_6XYOLwS18>8A(TZS*~PcntdDF|&<+I1i5xX67+$d-SKA#u8Oc zTJlO{&9u>%LT0}<`f99rntU042&SoNrf*=7rr888%{U9Tz&Kxy71@om+8TEHUfdcc zUizaw0WzM5=uZbT(I~Y12Iogu{P224m%2D_bQw~BjG;46$j-RQaATP0IBX1KHRReD z_IJ=Cb1(iLQ`Ehnsl4umVkY-_qnCzkVx2wjioD1q+fK1P8C;FH7VRzvk5KP3zT@Cu zCo+QF>G~sWy;>7SZTqRI>Jn@4l%5sXAGWteF<_ zXD}7|wU7(3;%PDtKLpd%LT*bn{WVJ|*aL&{AAEkoZk6u{Y~mk#Njf$nNQEAU1(jwQ z+r@6sW$Xb=Q9DCZdF>2`-Mq&}uAqYC`yOkhsYW;7mrBk{VOMOeZ72ZE$!_Y=wPHO#3h!FEIRFDT)m1zz2XRt&O;! zmep*8^*NtldY5N!yi8VMT;{ky>I`-ApR;n?tqZ_KsbQW|krratmb+HU|NICv8JGVQ_< zp`nmc_4j6~{>&cf1NmFFohZOQ>nj~7vrbH2IWnr>X7PBW6NfckPlf87k>abRsADPj z3h$>yXJk9~*9{4{S>@ZgzluaDr^AS`o%>+5Fzb(%#FRyG(b-EAbc~o06u} z3W28PXoc`%J@ygyvvX}fxHNt2#@brm^#c9mhQNAj&1zSk#Yzajfgjh6#&_s@j-B-j zxK2@0&6<-z33L<;&j$CiflZP&`1QGr_gJM(oePMHzEea+gVSX!Em{6lmNWD*i}R(J zGAtg>2BNf!hcjqdZSi395RCn0u|<-WLNCeFn``>%jnz?5i#qFVS7gi2(}POp9>jyW z5!q7Hi0nev%%#wAklF82Xe(AcP40#tf@!)G+L{7-d+5zv3y-4(Yp^0Z0V}hvh!XdZ z3)1}d>pj>78sYj)Oi}wqQ*&g$&hWijGuvb9Ep8Kq722&((3x$RWxOQqcUw(mz~MD& zx|Xn7SdfeTp$yO;aAgu2k;MQ#Drx6TGRA(h@ChOHR+DhP0j4f>%T(&?>v(F+f;UMp-9ISSQ8 z&QJg;C6DuDpE4lXSwNH)$#$hEt09?^F&RbHOe8xNGW$icEm-k1c_sW1Oj9IVtw~r5 zItwOX?jMh2c0fydh$u(}K85|zG$DdvEpg+=kP-?&7fCPc@26669B!pAekL{l`pw{ zPs_vCSCtA_U!gHZ;8WuA8yEQAJuwr-T+2YAX5#& z8Ty){)8K2e8gluXKY|wd?h{N=!|@!Z@){1sOm1KEd^+H;`x?)7XR{tV+|H(6ag6zR z-E6yVVV;ug$1!?weC;X9C~7)Z>BWRThclJRt~h~BAG^xBjmHv68_c!j4C}F+3y1Yy z`M%+NWjVt60Lg-03F;)-*$nn$BM_yvAIGLBt9ipp_+$uKGa>nxFp>L(np_G$ z1k)6f*XZh{VY1)?;AtV!C1LW35|g>Gb!--D>n@~5=L+7UU5!l$#aBTuKnjMumrHh& zkymt0){qN%Z-f>Z^4^3gio7(H8+loGfSKILyPJ-yJn)qbdq+}WudF%-eQ%!=^wqdZ z!r$W!2}#l@2D3>b3kY>Kvy}oLtB$V)KqdWAn~Xpyeo$ zy+d|810uf_h|(hRT`9_Hh^&TzyctG0^6?Ur<*;#QS!l4Mgc_Mo^0w^CY(wJ)QZO|BxMVaLjYX#bjad!3(D(^xk)iR| zFh$XrrgEdPWF|KnUrNU`{HQz|BtI_&B!}yd!R0s32`-zgC4uu+o4~{d47Ncm3e!hf zh=itF?eEo(R`KZRM%$3cszlU61(xTgoE?lK&?VrA6}p zlcKDKEa`GuIGa8FaY z;a)P68}4@tq++i}&4%;|&Ud)#7?7WJ$I;{}3E#Jc3DoX9kspWg5{;N>1-zTtN}XTs zRA)D`zf{uBzAG*SA^J&COM4VJ8wV+Cvi}*7+y^4p^v7T{LI8elvqH;iQFb|wZ2Z~q z_F;?Ol&1%GWbQ%g(7VzoQbyKHTXZ#K_G^n?i4{+i2jPccnyo6r`lOj5!3PY-KBP=C zLub*Q984{{EqV@*z5b;&#Shvv;XBjSa<^7$iH)^ln&zTabNR!Zzx1Z*#Yn+S(?haz z$tw{d2rx~ohFqrUF=&yQra!?HHBB^?+cZgLa+{`0gdX^%cCM$oXSf$4(dz9ciUEpi zFUZDdRl__h>iTbp78W{ZyQNg>yId>mD&;m0PfOb14YR$fvh~+A5zBcYCJE*6hw~M> zhVvnAF6foG{#AB4gGG1_h|*ewAEqd)`SxlE$g{|riKkCOX1{p)3|2f%Hk=4^7}FF_ zkB$z2hN*%Vz|^OZ+KQ?A3C4@}_+EKGev<^hHR9n1L`wL*1^DV>7-{kKTKMUeiRuBb zZo+GywWwh}4*HsD4KQye07(28&ioPonA6TIQW7T`cOX&9BV0SVlHs|<>-gza@w6NC z;GkbE`vv$=P#KlS`k5Iyh53q5{;kIP@=U$pXBIC3BKtR*@Q$uJaHwoc3f>hzW(D!S z6?^Qykz7cbaawh8)(@qh@+jFhT69Lv`b`=#akI+L`Vk~bsVL7MYcy(Jsa~koD^>hz zbA5tiiGYX#*n5DKFqo7Mz}JjQV>OTI4h&WQ6{&%|Jxj0YnZR4A$lcQ6X97_=nFi9S zM&eAMfDYjeIEiQwL%_S8BF%=shoC3SOMDnp)JvqPyj~)At@3X8yGXZe_%JtH_#)x+ z-)7}`y~E?pisF4kaj>|EE-!XSc!tp%N_iiHvCv^GtdwrQ@bi*(_CLODiY0myPnrN~ z5@y6J{I=|H2CwibAWG{M{&|YBnpda>fP52KGrhvkKxV&Q;TN&uY4RWNLoiLf!q8fS z%^i7SLT~~e%4d-_(I?y!^$D3r=z;48+upzdfNgN#E~@W&#(IV`QkR+?zvLYds283c zmKgConFt{JpG(;v;rCq}waJAbhKz)FxDJU@8vR-E4u>=Kf_sOj0Fm80#5+2yX7&!v z3fva@85r=BDKkzD72Y9AKc!Q#niicA@9;W9CT>=_clZ({N~tK7blzdhD>qsd_~<19 z*GR#G_eFTEL4h#^>L|QS0YL&iokY~j6b8dik;cn>JM@HkneV_9^)hK{j=W6yh^z)X zx!W1{2B&;P#;Ue^m~;0)M{t$;5gC_|e1U>+@e&`AiI&*eU-@W-XR9gnFldAh%HgTu z_H`eWwDUls#=eKyctrL;W&bm{zW)P=(z?E%re%-dBeJLS^x#{Wdk_zD#_1HLQREMi zHPd;&A2R!O-am{LPm_O#AA;%dBQieW)W$o(2Y3@7KuW9Yu6;>&ls+P>;HRS1ml4{D zPsg&7sTus=oGW1;!ZX5_Kt43g+4g|1oNvvH;De+GkeIS{2aNSDyEN6;YMoTmq`%G`t021#iYxfoe94brKQ z*{?x*9#%X}ZigR&>99fK6HXZHSD(LH!aSxO5vx876AeJbckUWfl=Njv+;Z>&A0D5ZJ* zM*yfVl6}qq)aL_HTA)5VMOh7~)fkYokTnyiH$rB=K)nqso+dZK55Y7A>SHV;pkcOP z1~7Xwk|$yI9*Wtef_Qbds2yIJ4Npc|@N8sk3ii-Y2|ir%43lKj=A!+MW>T}Zn3vUb|oJ3#TFV_RA_(nhEnAo*G9W4yM6I{ zB<-ASDbV^l3sC=v>~IFCe+Y=uLj4C*l+~bK4FGunSu>&jt&rI-)V~`mo+eMg55Y8r zda<`gieJNd!3p5}+mSX2=g&xk^BnvOh!jGtvlA+{{|nBUUF~fie1H@T!M`E9m5ks* z1c2bIhFl2#kI*7R@Mkea5uB!SBe-NHH-d}PD@+HvlVe^h8-}Mly`ohggW_{_-Xp|W zlKU=B&}c;QNFJVERJ20rZMT$KFD|eNXIE=Cn*WMxHGCRren|Al$5>8qiYw*=#zR1q z7SA`ND68SQ8UnH&Su^qcKVgXa#q*_D@if^DKLpbh&&3HET{~5TTkryi{tK=o@Nm!k z%C34R;Eptit{*BL3bK$Wb$>qg1?-Dm-EAoTbL5|)_{E&qHJ0Ldyy!NdIIAHSioX(N zPLIc5k12}cG?g30B{MUF;%H^FK5or`;;j1lh~k2?OeoH!6&ni=LA7XsJ#Mw#Qfl3D zsymbEQC#$wLfDZFz#Nuc&ft~58HijnUq2atXNs~KimM?YcOYvfiu;h+FN$}t z;%V}G@Ix>iMRBg33dIF4fa3d+I>|3j1<7KVnObKdQR@Ct&P{q0CrH6i{3Eg}$-cPg zHlR4GAs3224lObi|1(Tc6sM`&C@z`Fjp7&LIN+1YVxwN1EM@!*%g%HUEP35A`2G4h zi>0tGCx=q5FondC8{dUZqlg#pgRe2jP$K_J1rupTG}OM-5z;a$-l^zyqxDc}v| zRMoVPL99EOfw5f~ViqB*fCzl>_seg(ExcGX0V$N}jP{EMyrQcUjGwRrZGb z7{S%_W}k-4e!bbh#fqoNr$H_R)6|=lyN#qzBad$iMgS=O5=oO>*%20yP#-0SJ$J3f zB%HxlT33KC6_g6#I|=p6Mx+$<^Ul#V@fP=ge+T=(+}Y1^VwX7*K?%`ySwk*&_9+xP z4N6R7in_BjmD`Mbx0Fm0@?b{Zdb62KF@S9e80yd$+(6Ek}*l z1T>!s82k}H+wH*2M-;(@Anu-yxmLw{OTSU=v>3szO@u$qHCzSSDbSTR{TRPmY}zxSeF z!M|X6xzxl!S#MvkWTMs>>m3f3`PE9rt3zrvrMl!k?xF2Wxr1cOGn&noY0O3oVPWmM+%9?wR_mVDA

v(=brdF^)Zw%%~CwA1L6YD{{(3>9V< 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 and `Python +`_. We'll show you how to do some neat things. +How can you get a list of all |hisparc| stations in Denmark? What is the +position of station 201? Which stations had data on 20 October 2010? How +does the number of measured events change during a few weeks? This +tutorial will give you an overview of some of possibilities with the +|hisparc| |api|. For details on all available classes and methods, +please see the :doc:`api`. + +.. note:: + + We'll require you to know some basic programming, i.e. to understand + what an :code:`if` statement is and :code:`for` loop does. If you + are new to coding you can try a tutorial online, for instance + `Codeacademy `_, we recommend learning + Python or jQuery. + + +First look +---------- + +First we will just look at what this |api| is. The |api| can be accessed +via the internet by opening urls. Instead of a website you get data as a +response. This data is formatted as a JSON (JavaScript Object Notation), +this format can be understood by many programming languages. + +To see what options the |api| has we will look at it in a browser. Open +the following link in your browser (this will not work in Internet +Explorer): `https://data.hisparc.nl/api/ `_. + +You should now see some text, like this: + +.. code-block:: javascript + + {"base_url": "https://data.hisparc.nl/api/", + "clusters": "clusters/", + "clusters_in_country": "countries/{country_id}/", + "configuration": "station/{station_id}/config/{year}/{month}/{day}/", + "countries": "countries/", + "has_data": "station/{station_id}/data/{year}/{month}/{day}/", + ... + "subclusters_in_cluster": "clusters/{cluster_id}/"} + +This is the JSON, it is a dictionary (indicated by the :code:`{` and +:code:`}` enclosing brackets): an object which has keys and values. Each +key (:code:`"clusters"`, :code:`"has_data"`) refers to a value +(:code:`"clusters/"`, +:code:`"station/{station_id}/data/{year}/{month}/{day}/"`). + + +Cluster list +^^^^^^^^^^^^ + +This tells us that if we want a list of all clusters we need to use the +clusters option by appending :code:`"clusters/"` to the base url, +resulting in the following: +`https://data.hisparc.nl/api/clusters/ `_. + +With this result: + +.. code-block:: javascript + + [{"name": "Amsterdam", + "number": 0}, + {"name": "Utrecht", + "number": 1000}, + ... + {"name": "Karlsruhe", + "number": 70000}] + +This JSON is a list (indicated by the :code:`[` and :code:`]` enclosing +brackets) of dictionaries, one for each cluster. Each dictionary +contains the name and number of a cluster. This way information about +the network of stations can be retrieved. + + +Javascript example +------------------ + +The following code example will generate a webpage which will use the +|api| to get an up-to-date list of stations. It will then show a +drop-down menu from which a station can be selected, once you have +chosen a station you can click the :code:`Get info` button to make +Javascript get the station information. To try this you can either use +this example page: `jsFiddle `_ or create +your own HTML file with this code: + +.. code-block:: html + + + + + + + +

Station info

+

Choose a station:

+ +

+    
+    
+
+
+Python example
+--------------
+
+In this example we will use several standard Python libraries and the
+popular plotting library `matplotlib `_ (pylab).
+We start by importing the required libraries, one to get data from the
+urls, one to make working with dates easy and the plotting library. Then
+define the start values and perpare two empty lists in which the data
+can be placed. Then a while loop is used to loop over all days between
+datum and end_datum, reading each corresponding url. Finally a plot is
+made, setting the dates against their values.
+
+Start Python and type (or copy/paste without the :code:`>>>`) the
+following lines of code:
+
+.. code-block:: python
+
+    >>> from urllib.request import urlopen
+    >>> from datetime import date, timedelta
+    >>> from pylab import plot, show
+    >>> id = 501
+    >>> datum = date(2010, 10, 1)
+    >>> end_datum = date(2011, 2, 1)
+    >>> base = 'https://data.hisparc.nl/api/station/%d/num_events/%d/%d/%d'
+    >>> events = []
+    >>> dates = []
+    >>> while datum < end_datum:
+    ...     url = urlopen(base % (id, datum.year, datum.month, datum.day))
+    ...     events.append(url.read())
+    ...     dates.append(datum)
+    ...     datum += timedelta(days=1)
+    ...
+    >>> step(dates, events)
+    >>> show()
+
+
+SAPPHiRE
+^^^^^^^^
+
+The HiSPARC Python framework SAPPHiRE includes an API module. This module
+simplifies access to the API. See the SAPPHiRE documentation for more
+information:
+`https://docs.hisparc.nl/sapphire/ `_.
diff --git a/_sources/api_views.rst.txt b/_sources/api_views.rst.txt
new file mode 100644
index 000000000..6d9c8cdde
--- /dev/null
+++ b/_sources/api_views.rst.txt
@@ -0,0 +1,11 @@
+API Views Reference
+===================
+
+.. automodule:: publicdb.api.views
+   :members:
+   :undoc-members:
+
+
+Contents:
+
+.. toctree::
diff --git a/_sources/data_access.rst.txt b/_sources/data_access.rst.txt
new file mode 100644
index 000000000..83cccaeb4
--- /dev/null
+++ b/_sources/data_access.rst.txt
@@ -0,0 +1,105 @@
+.. include:: subst.inc
+
+Data access
+===========
+
+There are several ways in which the |hisparc| data can be accessed:
+
+- Via the Public database `download forms
+  `_.
+- Via Python using the |sapphire| framework (see `SAPPHiRE Tutorial
+  `_).
+- Via the `jSparc `_ web applications.
+
+To access metadata, like a list of all stations or information about a
+specific station see the :doc:`api_tutorial`.
+
+
+Download form
+-------------
+
+When looking at the data page for a station (i.e. `Kaj Munk College
+`_), you will see a 'Download
+event summary data' link on the right. When this link is clicked you
+will be taken to the `Data download form
+`_. On this page you can select
+the station, the start and end date for which you want to download the
+data. There is also an option to download weather data instead of events,
+however, not all stations gather weather data.
+
+When you click the Submit button without checking the checkbox to
+Download, the data should (Firefox always downloads the data) show up in
+your browser window. If you check the Download box the data will be
+downloaded to your PC as a csv file.
+
+This csv file can be read by many programs, including Excel. Use the
+Import option in Excel to make it recognize tabs as delimiter between
+columns.
+
+
+Downloading via Python
+----------------------
+
+.. note::
+
+    An easy to use module has been added to |sapphire| to download
+    data from the ESD. The following is an old (but working) example.
+
+This is an example of how to download the data from the Public database
+in Python. In this example we will download 1 hour of data for station
+202 on July 2, 2013.
+
+First load the required libraries (requires the numpy package).
+
+.. code-block:: python
+
+    >>> from datetime import datetime
+    >>> from urllib import urlencode
+    >>> from urllib.request import urlopen
+    >>> from StringIO import StringIO
+    >>> from numpy import genfromtxt
+
+Then define the url and place the start and end datetime in the query.
+To download weather data instead, replace 'events' by 'weather' in
+the url (and choose a station that has weather data, e.g. 3 or 501).
+
+.. note::
+
+    Do not pass the query to the urlopen 'data' argument because that
+    changes the request into a *POST* request, but you need a *GET*
+    request.
+
+.. code-block:: python
+
+    >>> url = 'https://data.hisparc.nl/data/202/events'
+    >>> start = str(datetime(2013, 7, 2, 11, 0))
+    >>> end = str(datetime(2013, 7, 2, 12, 0))
+    >>> query = urlencode({'download': False, 'start': start,'end': end})
+    >>> full_url = url + '?' + query
+
+Download the data and store it in a variable
+
+.. code-block:: python
+
+    >>> data = urlopen(full_url).read()
+
+Now use numpy to convert the data from csv to a numpy array.
+
+.. code-block:: python
+
+    >>> format = [('date', 'datetime64[D]'), ('time', '|S8'),
+                  ('timestamp', 'uint32'), ('nanoseconds', 'uint32'),
+                  ('pulseheights', '4int16'), ('integrals', '4int32'),
+                  ('n1', 'float32'), ('n2', 'float32'),
+                  ('n3', 'float32'), ('n4', 'float32'),
+                  ('t1', 'float32'), ('t2', 'float32'),
+                  ('t3', 'float32'), ('t4', 'float32'),
+                  ('t_trigger', 'float32'),
+                  ('zenith', 'int16'), ('azimuth', 'int16')]
+    >>> a = genfromtxt(StringIO(data), delimiter="\t", dtype=format)
+    >>> print(a[0])
+    (datetime.date(2013, 7, 2), '11:00:02', 1372762802L, 466307811L,
+     [78, 798, -1, -1], [535, 10882, -1, -1],
+     0.14720000326633453, 3.854599952697754, -1.0, -1.0,
+     345.0, 12.5, -1.0, -1.0, 345.0, -999, -999)
diff --git a/_sources/hisparc_maps.rst.txt b/_sources/hisparc_maps.rst.txt
new file mode 100644
index 000000000..8c7d5b44c
--- /dev/null
+++ b/_sources/hisparc_maps.rst.txt
@@ -0,0 +1,110 @@
+.. include:: subst.inc
+
+HiSPARC maps
+============
+
+Each |hisparc| station is equipped with a GPS antenne. This GPS is used
+to for time synchronization between stations and to determine the exact
+location of each station. All these locations are stored in our
+database. The GPS positions can be found on the data pages of stations,
+via the API (:doc:`api`) and in the raw data.
+
+
+Map
+---
+
+Using the `Leafet `_ library with `CARTO
+`_ maps tiles (based on `OpenStreetMap
+`_ data) we are able to visualize the
+detector network by showing the locations of the stations on a map.
+
+Here is an overview of the network: `Stations on map
+`_
+
+
+Station info
+^^^^^^^^^^^^
+
+When you click on a station marker a popup will show information about
+that station, its name and cluster. If the station has data the name of
+the station will be a link to its data page.
+
+
+Status
+^^^^^^
+
+The stations on the map can have one of 4 colors to indicate the current
+status of that station.
+
+- Green: when a station is operating properly
+- Yellow: it is responding to the server but has a problem
+- Red: it is completely unresponsive (offline)
+- Gray: it is is no longer active or the status can't be determined.
+
+
+Embedding
+---------
+
+On several public database pages a map is embedded to show the station
+location or provide an overview of multiple stations. Moreover, maps are
+also used on our main website to give an overview of the station
+organization and clustering (e.g. `Bristol
+`_, `Science
+Park
+`_
+). This is accomplished by placing an iframe on those pages that
+shows another page which only has the map as its content. Example code:
+
+.. code-block:: html
+
+    
+
+Result:
+
+.. raw:: html
+
+    
+ +
+ + +Syntax +^^^^^^ + +To show a map of a specific region or location, use the syntax explained +here. First start with the base url:: + + https://data.hisparc.nl/maps/ + +When no extra options are given the page zooms and positions the map +such that all stations fit in the window. But you can also focus on a +specific region or station. Several levels of regions are possible:: + + https://data.hisparc.nl/maps/[Country]/[Cluster]/[Subcluster]/ + https://data.hisparc.nl/maps/[Station number]/ + +An overview of countries, clusters and subclusters can be found on +https://data.hisparc.nl/ . First you can choose to focus on a Country: + +- https://data.hisparc.nl/maps/Netherlands/ +- https://data.hisparc.nl/maps/Denmark/ + +Then focus more closely on a cluster, note that you also need to give +the country: + +- https://data.hisparc.nl/maps/Netherlands/Enschede/ +- https://data.hisparc.nl/maps/Netherlands/Utrecht/ +- https://data.hisparc.nl/maps/United%20Kingdom/Bristol/ + +And to focus on a subcluster, also specifying the country and cluster: + +- https://data.hisparc.nl/maps/Netherlands/Amsterdam/Zaanstad/ +- https://data.hisparc.nl/maps/Netherlands/Enschede/Enschede/ + +Finally you can also focus on one specific station by simply giving its +station number: + +- https://data.hisparc.nl/maps/8005/ +- https://data.hisparc.nl/maps/8103/ diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 000000000..7cd87648d --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,26 @@ +Public Database documentation! +============================== + +The HiSPARC Public Database is the interface through which everyone can access +the data and our station administration is done. + +Contents: + +.. toctree:: + :maxdepth: 2 + + data_access + api_tutorial + hisparc_maps + station_layout + api + status_display + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/_sources/station_layout.rst.txt b/_sources/station_layout.rst.txt new file mode 100644 index 000000000..441bb23d6 --- /dev/null +++ b/_sources/station_layout.rst.txt @@ -0,0 +1,63 @@ +.. include:: subst.inc + +HiSPARC station layout +====================== + +Each |hisparc| station has a GPS antenne and either 2 or 4 scintillator +detectors. This GPS is used to determine the exact location of the +station. However, the GPS is often not at the center of the station, +moreover, not all stations are oriented the same way, and the distances +between detector may differ. For reconstruction of the measured data it +is important to know the location of each detector, this section +explains how the location of the detectors can be measured and +communicated to us. + + +Compass coordinates +------------------- + +The coordinate system we have chosen for describing the position of +detectors is illustrated in the following figure. + +.. image:: images/coordinate_system.png + :width: 313px + +For each detector 3 (or 4) coordinates need to be determined: + +- First the distance (:code:`r`) from the GPS to the center of the + scintillator (in meters). +- Next the alpha angle (:code:`α`) which is the clock-wise turning angle + between North and the detector as seen from the GPS (in degrees). +- A height (:code:`z`) coordinate can be measured if there is a + significant altitude difference between the GPS antenna and the + detectors, or if the detectors are not at the same height. Up is + positive (in meters). +- The rotation of the detector is described by the beta angle + (:code:`β`), which is the clock-wise turning rotation of the long side + of the detector relative to North (in degrees). + +For more information about the coordinate systems used in HiSPARC see: +`Coordinate systems and units in HiSPARC +`_. + +For Dutch schools we have an assignment sheet in the infopakket which +walks students through the process of measuring the station layout: +`De stationsplattegrond +`_. + + +Submitting the measurements +--------------------------- + +New layouts can be submitted via the `layout submit form +`_. A verification e-mail will be sent +to the submitter. The submitted measurements will be reviewed before they are +made available on the website and via the API. + + +Accessing the data +------------------ + +The detector coordinates can be accessed via the :doc:`API `. +These can, for example, be used when analysing data or when making a schematic +drawing of the station layout. diff --git a/_sources/status_display.rst.txt b/_sources/status_display.rst.txt new file mode 100644 index 000000000..36a72f40d --- /dev/null +++ b/_sources/status_display.rst.txt @@ -0,0 +1,13 @@ +Status Display Reference +======================== + +.. automodule:: publicdb.status_display + :members: + :undoc-members: + + +Contents: + +.. toctree:: + + status_display_views diff --git a/_sources/status_display_views.rst.txt b/_sources/status_display_views.rst.txt new file mode 100644 index 000000000..aac40fa8b --- /dev/null +++ b/_sources/status_display_views.rst.txt @@ -0,0 +1,11 @@ +Status Display Views Reference +============================== + +.. automodule:: publicdb.status_display.views + :members: + :undoc-members: + + +Contents: + +.. toctree:: diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 000000000..f316efcb4 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,925 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 000000000..4d67807d1 --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 000000000..867e7247d --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.4', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/favicon.ico b/_static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..2632b900af50d910fc8f276420be1a235eb8c5c2 GIT binary patch literal 4286 zcma)8OQ=p^6g}P|T?rWoWuhdBB+)f7VuUg?QA#Py#NZ~6%uEbSq`YEA29%V?0EHt` z2J*-sk;H^ZK5HF&9qa$j_shAhyZ5)(+IyXS`u}rpRgJ>Wym=LWSLdfz)y%4@762$! zYXH^s8_Yep%8@AK0+*P{Lcp#OA0^Jj(c*odD(L)}x&K;E~r z>Wbu*E2>8v;&&M}YY<*W-L9 z>U=iit*`M$t&QS5lGnUki}NHvyD>J;mb&OUX8g3$9BIWddM=*P^U%ykjXUceR$Ko8 ztIy77auy-I^U9@BbZuz(y`le4peG*rEOoDksmI3 z=QU{C=Tge$sXl4qJPv2R*YvFQ&OIG`^KR1&_IiIlGv~ysUuV}L=ie;(^O;`^-5B*z zPvrfo4~o{$Jud_6tu`8GzR!OE^1l@xt+(lUZ#Z^8)6rApgIgLNcjK&G^tYV7kMr4n zrnmbe*9?6Y8(#IScM0m;@n%-n-mg?=zmU~hfAZv9hrExMCUhNt@Y?|Te{>(^9ytqW z_v6`l=Hl~ua3z0!*Xh4lJ;>X=R8uU?r{2)Fzxo()_4(thcm0##eNK~me`t#HbAO$^ z-~9FY=KqS^eT8&+AJ5|4ANA%w21WIFKXUDV1^FU?-p^w0804LuS@T&q|I=5z_gF6f zi_l#K=)XZcBd+!yJU34MtuE_tc+>m+%l{>2Q}@|*@?-Rwo<|=_Z2$W?Wgck#y)X3g z=ib!ql*anoy;PGXX0-F2SB_ZZ3;w^dxkX>j&2-KDLcMQ)@rniieNj_iC%Uh4%feD*}=|8~EhJU9RLdC)W0u~w>w?g%(~pHQFA^*+^0kveI`doAZoqupn@ zM!kcg^|!v#l2bk?hGrjl`kzye=K7g4y#Bwr`V>2TZ}$wP-ma0D_QjZ%0zPkIs9*e&7HwA*Gi?bzRS`>xaX@NL}Age{e6|7$R=tOxy|7h&5U< IIh_pr22!tZkN^Mx literal 0 HcmV?d00001 diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/_static/header.png b/_static/header.png new file mode 100644 index 0000000000000000000000000000000000000000..383625f38ea5244e6b401fe8d3de52432ba78d40 GIT binary patch literal 3210 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 wHt@W;Ps#ng(R*rXRPZYB0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..d96755fdaf8bb2214971e0db9c1fd3077d7c419d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu=nj kDsEF_5m^0CR;1wuP-*O&G^0G}KYk!hp00i_>zopr08q^qX#fBK literal 0 HcmV?d00001 diff --git a/_static/nature.css b/_static/nature.css new file mode 100644 index 000000000..ba033b0db --- /dev/null +++ b/_static/nature.css @@ -0,0 +1,252 @@ +/* + * nature.css_t + * ~~~~~~~~~~~~ + * + * Sphinx stylesheet -- nature theme. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Arial, sans-serif; + font-size: 100%; + background-color: #fff; + color: #555; + margin: 0; + padding: 0; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.document { + background-color: #eee; +} + +div.body { + background-color: #ffffff; + color: #3E4349; + padding: 0 30px 30px 30px; + font-size: 0.9em; +} + +div.footer { + color: #555; + width: 100%; + padding: 13px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #444; + text-decoration: underline; +} + +div.related { + background-color: #6BA81E; + line-height: 32px; + color: #fff; + text-shadow: 0px 1px 0 #444; + font-size: 0.9em; +} + +div.related a { + color: #E2F3CC; +} + +div.sphinxsidebar { + font-size: 0.75em; + line-height: 1.5em; +} + +div.sphinxsidebarwrapper{ + padding: 20px 0; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Arial, sans-serif; + color: #222; + font-size: 1.2em; + font-weight: normal; + margin: 0; + padding: 5px 10px; + background-color: #ddd; + text-shadow: 1px 1px 0 white +} + +div.sphinxsidebar h4{ + font-size: 1.1em; +} + +div.sphinxsidebar h3 a { + color: #444; +} + + +div.sphinxsidebar p { + color: #888; + padding: 5px 20px; +} + +div.sphinxsidebar p.topless { +} + +div.sphinxsidebar ul { + margin: 10px 20px; + padding: 0; + color: #000; +} + +div.sphinxsidebar a { + color: #444; +} + +div.sphinxsidebar input { + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar .searchformwrapper { + margin-left: 20px; + margin-right: 20px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #005B81; + text-decoration: none; +} + +a:hover { + color: #E32E00; + text-decoration: underline; +} + +a:visited { + color: #551A8B; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Arial, sans-serif; + background-color: #BED4EB; + font-weight: normal; + color: #212224; + margin: 30px 0px 10px 0px; + padding: 5px 0 5px 10px; + text-shadow: 0px 1px 0 white +} + +div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 150%; background-color: #C8D5E3; } +div.body h3 { font-size: 120%; background-color: #D8DEE3; } +div.body h4 { font-size: 110%; background-color: #D8DEE3; } +div.body h5 { font-size: 100%; background-color: #D8DEE3; } +div.body h6 { font-size: 100%; background-color: #D8DEE3; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + line-height: 1.5em; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +nav.contents, +aside.topic, +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 10px; + line-height: 1.2em; + border: 1px solid #C6C9CB; + font-size: 1.1em; + margin: 1.5em 0 1.5em 0; + -webkit-box-shadow: 1px 1px 1px #d8d8d8; + -moz-box-shadow: 1px 1px 1px #d8d8d8; +} + +code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ + font-size: 1.1em; + font-family: monospace; +} + +.viewcode-back { + font-family: Arial, sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} + +div.code-block-caption { + background-color: #ddd; + color: #222; + border: 1px solid #C6C9CB; +} \ No newline at end of file diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 0000000000000000000000000000000000000000..7107cec93a979b9a5f64843235a16651d563ce2d GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^+#t*WBp7;*Yy1LIik>cxAr*|t7R?Mi>2?kWtu>-2 m3q%Vub%g%s<8sJhVPMczOq}xhg9DJoz~JfX=d#Wzp$Pyb1r*Kz literal 0 HcmV?d00001 diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 000000000..0d49244ed --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 000000000..b08d58c9b --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,620 @@ +/* + * searchtools.js + * ~~~~~~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for the full-text search. + * + * :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename] = item; + + let listItem = document.createElement("li"); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = _( + "Search finished, found ${resultCount} page(s) matching the search query." + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '
" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/api.html b/api.html new file mode 100644 index 000000000..9ab5b7f8e --- /dev/null +++ b/api.html @@ -0,0 +1,145 @@ + + + + + + + + API Reference — Public Database 0.4 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

API Reference

+

Application Programming Interface for HiSPARC Public Database

+

The API simplifies data access for data contained in the +HiSPARC Public Database. It was born out of the +need for easy access to up-to-date information about stations.

+

Contents:

+ +
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/api_tutorial.html b/api_tutorial.html new file mode 100644 index 000000000..c4146f9f9 --- /dev/null +++ b/api_tutorial.html @@ -0,0 +1,286 @@ + + + + + + + + API Tutorial — Public Database 0.4 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

API Tutorial

+

The HiSPARC API (Application Programming Interface) simplifies +metadata access from other applications. In this tutorial, we’ll give +some examples of how this data can be accessed and used with Javascript +(jQuery) and Python. We’ll show you how to do some neat things. +How can you get a list of all HiSPARC stations in Denmark? What is the +position of station 201? Which stations had data on 20 October 2010? How +does the number of measured events change during a few weeks? This +tutorial will give you an overview of some of possibilities with the +HiSPARC API. For details on all available classes and methods, +please see the API Reference.

+
+

Note

+

We’ll require you to know some basic programming, i.e. to understand +what an if statement is and for loop does. If you +are new to coding you can try a tutorial online, for instance +Codeacademy, we recommend learning +Python or jQuery.

+
+
+

First look

+

First we will just look at what this API is. The API can be accessed +via the internet by opening urls. Instead of a website you get data as a +response. This data is formatted as a JSON (JavaScript Object Notation), +this format can be understood by many programming languages.

+

To see what options the API has we will look at it in a browser. Open +the following link in your browser (this will not work in Internet +Explorer): https://data.hisparc.nl/api/.

+

You should now see some text, like this:

+
{"base_url": "https://data.hisparc.nl/api/",
+ "clusters": "clusters/",
+ "clusters_in_country": "countries/{country_id}/",
+ "configuration": "station/{station_id}/config/{year}/{month}/{day}/",
+ "countries": "countries/",
+ "has_data": "station/{station_id}/data/{year}/{month}/{day}/",
+ ...
+ "subclusters_in_cluster": "clusters/{cluster_id}/"}
+
+
+

This is the JSON, it is a dictionary (indicated by the { and +} enclosing brackets): an object which has keys and values. Each +key ("clusters", "has_data") refers to a value +("clusters/", +"station/{station_id}/data/{year}/{month}/{day}/").

+
+

Cluster list

+

This tells us that if we want a list of all clusters we need to use the +clusters option by appending "clusters/" to the base url, +resulting in the following: +https://data.hisparc.nl/api/clusters/.

+

With this result:

+
[{"name": "Amsterdam",
+  "number": 0},
+ {"name": "Utrecht",
+  "number": 1000},
+ ...
+ {"name": "Karlsruhe",
+  "number": 70000}]
+
+
+

This JSON is a list (indicated by the [ and ] enclosing +brackets) of dictionaries, one for each cluster. Each dictionary +contains the name and number of a cluster. This way information about +the network of stations can be retrieved.

+
+
+
+

Javascript example

+

The following code example will generate a webpage which will use the +API to get an up-to-date list of stations. It will then show a +drop-down menu from which a station can be selected, once you have +chosen a station you can click the Get info button to make +Javascript get the station information. To try this you can either use +this example page: jsFiddle or create +your own HTML file with this code:

+
<html>
+<head>
+<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
+<script>
+    $(function() {
+        // Get an up-to-date list of HiSPARC stations
+        $.getJSON(
+            'https://data.hisparc.nl/api/stations/',
+            function(data) {
+                // Create the drop-down menu
+                var select = $('<select>');
+                var id, name;
+                for (var i in data) {
+                    id = data[i].number;
+                    name = data[i].name;
+                    select.append($('<option>').attr('value', id).text(id + ' - ' + name));}
+                $('#station_list').append(select);});
+
+        // Attach a function to the Get info button
+        $('#get_station').on('click', function() {
+            var id = $('#station_list').find('select').val();
+            // Get info for selected station and display it in a nice way
+            $.getJSON('https://data.hisparc.nl/api/station/' + id + '/',
+                      function(data) {
+                          $('#station_info').text(JSON.stringify(data, undefined, 4));
+                      });
+            });
+        });
+</script>
+</head>
+<body style="font-family: sans-serif;">
+    <h2>Station info</h2>
+    <p id="station_list">Choose a station: </p>
+    <input type="submit" id="get_station" value="Get info">
+    <pre id="station_info"></pre>
+</body>
+</html>
+
+
+
+
+

Python example

+

In this example we will use several standard Python libraries and the +popular plotting library matplotlib (pylab). +We start by importing the required libraries, one to get data from the +urls, one to make working with dates easy and the plotting library. Then +define the start values and perpare two empty lists in which the data +can be placed. Then a while loop is used to loop over all days between +datum and end_datum, reading each corresponding url. Finally a plot is +made, setting the dates against their values.

+

Start Python and type (or copy/paste without the >>>) the +following lines of code:

+
>>> from urllib.request import urlopen
+>>> from datetime import date, timedelta
+>>> from pylab import plot, show
+>>> id = 501
+>>> datum = date(2010, 10, 1)
+>>> end_datum = date(2011, 2, 1)
+>>> base = 'https://data.hisparc.nl/api/station/%d/num_events/%d/%d/%d'
+>>> events = []
+>>> dates = []
+>>> while datum < end_datum:
+...     url = urlopen(base % (id, datum.year, datum.month, datum.day))
+...     events.append(url.read())
+...     dates.append(datum)
+...     datum += timedelta(days=1)
+...
+>>> step(dates, events)
+>>> show()
+
+
+
+

SAPPHiRE

+

The HiSPARC Python framework SAPPHiRE includes an API module. This module +simplifies access to the API. See the SAPPHiRE documentation for more +information: +https://docs.hisparc.nl/sapphire/.

+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/api_views.html b/api_views.html new file mode 100644 index 000000000..657332ab1 --- /dev/null +++ b/api_views.html @@ -0,0 +1,397 @@ + + + + + + + + API Views Reference — Public Database 0.4 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

API Views Reference

+
+
+clusters(request, country_number=None)
+

Get cluster list

+

Retrieve a list of all clusters or only the clusters in a specific country. +By cluster we here mean the main clusters, which contain subclusters.

+
+
Parameters:
+

country_number – a country number identifier, give this to only get +clusters from a specific country.

+
+
Returns:
+

list of dictionaries containing the name and number of all +clusters that matched the given parameters.

+
+
+
+ +
+
+config(request, station_number, date=None)
+

Get station config settings

+

Retrieve the entire configuration of a station. If no date if given the +latest config will be sent, otherwise the latest on or before the given +date.

+
+
Parameters:
+
    +
  • station_number – a station number identifier.

  • +
  • date – the date for which to get a configuration.

  • +
+
+
Returns:
+

dictionary containing the entire configuration from +the HiSPARC DAQ.

+
+
+
+ +
+
+countries(request)
+

Get country list

+

Retrieve a list of all countries.

+
+
Returns:
+

list of dictionaries containing the name and number of +all countries.

+
+
+
+ +
+
+get_cluster_dict(country=None)
+
+ +
+
+get_country_dict()
+
+ +
+
+get_event_traces(request, station_number, ext_timestamp)
+

Get the traces for an event

+
+
Parameters:
+
    +
  • station_number – a station number identifier.

  • +
  • ext_timestamp – extended timestamp (nanoseconds since UNIX epoch).

  • +
  • raw – (optional, GET) if present get the raw trace, i.e. without +subtracted baseline.

  • +
+
+
Returns:
+

two or four traces.

+
+
+
+ +
+
+get_station_dict(subcluster=None)
+

Return list of station numbers and names

+

For all non-test stations in the given subcluster

+
+ +
+
+get_subcluster_dict(cluster=None)
+
+ +
+
+has_data(request, station_number, type=None, year=None, month=None, date=None)
+

Check for presence of cosmic ray data

+

Find out if the given station has measured shower data, either on a +specific date, or at all.

+
+
Parameters:
+
    +
  • station_number – a stationn number identifier.

  • +
  • type – the data type: events, singles or weather.

  • +
  • year,month,date – the date, this has to be within the time +HiSPARC has been operational and can be as specific as +you desire.

  • +
+
+
Returns:
+

boolean, True if the given station has data, False otherwise.

+
+
+
+ +
+
+json_dict(result)
+

Create a json HTTPResponse

+
+ +
+
+man(request)
+

Give overview of the possible urls

+
+ +
+
+network_status(request)
+

Get status of the network

+
+
Returns:
+

dictionary containing status info for each station.

+
+
+
+ +
+
+num_events(request, station_number, year=None, month=None, date=None, hour=None)
+

Get number of events for a station

+

Retrieve the number of events that a station has measured during its +entire operation or during a specific period, which can be a year, +month, day or an hour.

+
+
Parameters:
+
    +
  • station_number – a stationn number identifier.

  • +
  • year,month,date,hour – the date, this has to be within the time +HiSPARC has been operational and can be as specific as you desire.

  • +
+
+
Returns:
+

integer containing the total number of events ever recorded by +the given station.

+
+
+
+ +
+
+station(request, station_number, year=None, month=None, date=None)
+

Get station info

+

Retrieve general information about a station. If no date if given +the latest valid info will be sent, otherwise the latest on or +before the given date.

+
+
Parameters:
+
    +
  • station_number – a station number identifier.

  • +
  • date – the date for which to get station info.

  • +
+
+
Returns:
+

dictionary containing info about the station. Most importantly, +this contains information about the location of the station GPS +and the relative locations of the individual scintillators.

+
+
+
+ +
+
+stations(request, subcluster_number=None)
+

Get station list

+

Retrieve a list of all stations or all stations in a subcluster.

+
+
Parameters:
+

subcluster_number – a subcluster number identifier. If given, only +stations belonging to that subcluster will be included in the list.

+
+
Returns:
+

list containing dictionaries which consist of the name and number +of each station (matching the subcluster).

+
+
+
+ +
+
+stations_with_data(request, type=None, year=None, month=None, date=None)
+

Get stations with event or weather data

+

Retrieve a list of all stations which have recorded events, singles or +weather data in the given year, month, day or at all.

+
+
Parameters:
+
    +
  • type – data type to check for: events, singles or weather.

  • +
  • year,month,date – the date, this has to be within the time +HiSPARC has been operational and can be as specific as you desire.

  • +
+
+
Returns:
+

list of dictionaries containing the name and number of each +station that has measured weather data in the given year.

+
+
+
+ +
+
+subclusters(request, cluster_number=None)
+

Get subcluster list

+

Retrieve a list of all subclusters or all subclusters in a specific +cluster.

+
+
Parameters:
+

cluster_number – a cluster number identifier, give this to only get +subclusters from this cluster.

+
+
Returns:
+

list of dictionaries containing the name and number of all +subclusters that matched the given parameters.

+
+
+
+ +
+
+validate_date(date)
+

Check if date is outside HiSPARC project range

+

If not valid, a 404 (Not Found) should be returned to the user.

+
+
Returns:
+

boolean, True if the date is in the range, False otherwise.

+
+
+
+ +

Contents:

+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/data_access.html b/data_access.html new file mode 100644 index 000000000..975431afd --- /dev/null +++ b/data_access.html @@ -0,0 +1,207 @@ + + + + + + + + Data access — Public Database 0.4 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

Data access

+

There are several ways in which the HiSPARC data can be accessed:

+ +

To access metadata, like a list of all stations or information about a +specific station see the API Tutorial.

+
+

Download form

+

When looking at the data page for a station (i.e. Kaj Munk College), you will see a ‘Download +event summary data’ link on the right. When this link is clicked you +will be taken to the Data download form. On this page you can select +the station, the start and end date for which you want to download the +data. There is also an option to download weather data instead of events, +however, not all stations gather weather data.

+

When you click the Submit button without checking the checkbox to +Download, the data should (Firefox always downloads the data) show up in +your browser window. If you check the Download box the data will be +downloaded to your PC as a csv file.

+

This csv file can be read by many programs, including Excel. Use the +Import option in Excel to make it recognize tabs as delimiter between +columns.

+
+
+

Downloading via Python

+
+

Note

+

An easy to use module has been added to SAPPHiRE to download +data from the ESD. The following is an old (but working) example.

+
+

This is an example of how to download the data from the Public database +in Python. In this example we will download 1 hour of data for station +202 on July 2, 2013.

+

First load the required libraries (requires the numpy package).

+
>>> from datetime import datetime
+>>> from urllib import urlencode
+>>> from urllib.request import urlopen
+>>> from StringIO import StringIO
+>>> from numpy import genfromtxt
+
+
+

Then define the url and place the start and end datetime in the query. +To download weather data instead, replace ‘events’ by ‘weather’ in +the url (and choose a station that has weather data, e.g. 3 or 501).

+
+

Note

+

Do not pass the query to the urlopen ‘data’ argument because that +changes the request into a POST request, but you need a GET +request.

+
+
>>> url = 'https://data.hisparc.nl/data/202/events'
+>>> start = str(datetime(2013, 7, 2, 11, 0))
+>>> end = str(datetime(2013, 7, 2, 12, 0))
+>>> query = urlencode({'download': False, 'start': start,'end': end})
+>>> full_url = url + '?' + query
+
+
+

Download the data and store it in a variable

+
>>> data = urlopen(full_url).read()
+
+
+

Now use numpy to convert the data from csv to a numpy array.

+
>>> format = [('date', 'datetime64[D]'), ('time', '|S8'),
+              ('timestamp', 'uint32'), ('nanoseconds', 'uint32'),
+              ('pulseheights', '4int16'), ('integrals', '4int32'),
+              ('n1', 'float32'), ('n2', 'float32'),
+              ('n3', 'float32'), ('n4', 'float32'),
+              ('t1', 'float32'), ('t2', 'float32'),
+              ('t3', 'float32'), ('t4', 'float32'),
+              ('t_trigger', 'float32'),
+              ('zenith', 'int16'), ('azimuth', 'int16')]
+>>> a = genfromtxt(StringIO(data), delimiter="\t", dtype=format)
+>>> print(a[0])
+(datetime.date(2013, 7, 2), '11:00:02', 1372762802L, 466307811L,
+ [78, 798, -1, -1], [535, 10882, -1, -1],
+ 0.14720000326633453, 3.854599952697754, -1.0, -1.0,
+ 345.0, 12.5, -1.0, -1.0, 345.0, -999, -999)
+
+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html new file mode 100644 index 000000000..296cf932c --- /dev/null +++ b/genindex.html @@ -0,0 +1,390 @@ + + + + + + + Index — Public Database 0.4 documentation + + + + + + + + + + + + +
+
+
+
+ + +

Index

+ +
+ C + | G + | H + | J + | L + | M + | N + | P + | S + | T + | V + +
+

C

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

J

+ + +
+ +

L

+ + + +
+ +

M

+ + +
+ +

N

+ + + +
+ +

P

+ + + +
    +
  • + publicdb.api.views + +
  • +
  • + publicdb.status_display + +
  • +
  • + publicdb.status_display.views + +
  • +
+ +

S

+ + + +
+ +

T

+ + +
+ +

V

+ + +
+ + + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/hisparc_maps.html b/hisparc_maps.html new file mode 100644 index 000000000..94a0d6234 --- /dev/null +++ b/hisparc_maps.html @@ -0,0 +1,218 @@ + + + + + + + + HiSPARC maps — Public Database 0.4 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

HiSPARC maps

+

Each HiSPARC station is equipped with a GPS antenne. This GPS is used +to for time synchronization between stations and to determine the exact +location of each station. All these locations are stored in our +database. The GPS positions can be found on the data pages of stations, +via the API (API Reference) and in the raw data.

+
+

Map

+

Using the Leafet library with CARTO maps tiles (based on OpenStreetMap data) we are able to visualize the +detector network by showing the locations of the stations on a map.

+

Here is an overview of the network: Stations on map

+
+

Station info

+

When you click on a station marker a popup will show information about +that station, its name and cluster. If the station has data the name of +the station will be a link to its data page.

+
+
+

Status

+

The stations on the map can have one of 4 colors to indicate the current +status of that station.

+
    +
  • Green: when a station is operating properly

  • +
  • Yellow: it is responding to the server but has a problem

  • +
  • Red: it is completely unresponsive (offline)

  • +
  • Gray: it is is no longer active or the status can’t be determined.

  • +
+
+
+
+

Embedding

+

On several public database pages a map is embedded to show the station +location or provide an overview of multiple stations. Moreover, maps are +also used on our main website to give an overview of the station +organization and clustering (e.g. Bristol, Science +Park +). This is accomplished by placing an iframe on those pages that +shows another page which only has the map as its content. Example code:

+
<iframe src="https://data.hisparc.nl/maps/Netherlands/Amsterdam/Science%20Park/"
+        scrolling="no" frameborder="0" width="600" height="300"></iframe>
+
+
+

Result:

+
+ +
+

Syntax

+

To show a map of a specific region or location, use the syntax explained +here. First start with the base url:

+
https://data.hisparc.nl/maps/
+
+
+

When no extra options are given the page zooms and positions the map +such that all stations fit in the window. But you can also focus on a +specific region or station. Several levels of regions are possible:

+
https://data.hisparc.nl/maps/[Country]/[Cluster]/[Subcluster]/
+https://data.hisparc.nl/maps/[Station number]/
+
+
+

An overview of countries, clusters and subclusters can be found on +https://data.hisparc.nl/ . First you can choose to focus on a Country:

+ +

Then focus more closely on a cluster, note that you also need to give +the country:

+ +

And to focus on a subcluster, also specifying the country and cluster:

+ +

Finally you can also focus on one specific station by simply giving its +station number:

+ +
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..84d1444b7 --- /dev/null +++ b/index.html @@ -0,0 +1,156 @@ + + + + + + + + Public Database documentation! — Public Database 0.4 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

Public Database documentation!

+

The HiSPARC Public Database is the interface through which everyone can access +the data and our station administration is done.

+

Contents:

+ +
+
+

Indices and tables

+ +
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..188acff84f477dd0de37fd80b8051cc14566400c GIT binary patch literal 987 zcmV<110?(-AX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkVbz*F3 zV<1FfbYWs)b7cx6AXa5^b7^mGIv_AEGzudiRA^-&a%F8{X>Md?av*PJAarPHb0B7E zY-J#6b0A}HZE$jBb8}^6Aa!$TZf78RY-wUH3V7PRSxa-9Fc7};E9kUWdzx!*ndZ>U zv>i{}$yFo7+9(wg)x!z@zIuQS6elepZuV;T`*yXvdQq8-QIcm{T+y_uZ%dII2I=S2 z{@)h5WFLcM^C{gVRY!SyqVS@ICdfbAiJx~(0*UltSo9@iA)|9m`5wZE2$092gM#trdx?YWwEFVw- ztXdF`3l2yNyM6KnQT?tt`ldP?wdt~@Vb5j0G;p+{YYT4iX>Nht^J!G@kvG02pqYQ4 zi2ywMD7ye~3`msK?I(dq=~<)H`Pl?VN=biccM{E|9JazStO zJHR`iBJWRTcb?R0n9?5NeQG`=rN~EotLjZV5Kz8{H~ipbXY?JjU2Sj8yl<`Sm6{ZN z!ypSb`!K%4M@ag|t8Rq-k^Y>t-+;ncGWfJH02zGQNcW+??i=k(=EsWlI#{=k29U#& J`U7|IeQqkH(U$-K literal 0 HcmV?d00001 diff --git a/py-modindex.html b/py-modindex.html new file mode 100644 index 000000000..ad7bc20e9 --- /dev/null +++ b/py-modindex.html @@ -0,0 +1,121 @@ + + + + + + + Python Module Index — Public Database 0.4 documentation + + + + + + + + + + + + + + + +
+
+
+
+ + +

Python Module Index

+ +
+ p +
+ + + + + + + + + + + + + + + + + + + +
 
+ p
+ publicdb +
    + publicdb.api +
    + publicdb.api.views +
    + publicdb.status_display +
    + publicdb.status_display.views +
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 000000000..06275aeac --- /dev/null +++ b/search.html @@ -0,0 +1,103 @@ + + + + + + + Search — Public Database 0.4 documentation + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Search

+ + + + +

+ Searching for multiple words only shows matches that contain + all words. +

+ + +
+ + + +
+ + +
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 000000000..9630da3ee --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"API Reference": [[0, null]], "API Tutorial": [[1, null]], "API Views Reference": [[2, null]], "Accessing the data": [[6, "accessing-the-data"]], "Cluster list": [[1, "cluster-list"]], "Compass coordinates": [[6, "compass-coordinates"]], "Data access": [[3, null]], "Download form": [[3, "download-form"]], "Downloading via Python": [[3, "downloading-via-python"]], "Embedding": [[4, "embedding"]], "First look": [[1, "first-look"]], "HiSPARC maps": [[4, null]], "HiSPARC station layout": [[6, null]], "Indices and tables": [[5, "indices-and-tables"]], "Javascript example": [[1, "javascript-example"]], "Map": [[4, "map"]], "Public Database documentation!": [[5, null]], "Python example": [[1, "python-example"]], "SAPPHiRE": [[1, "sapphire"]], "Station info": [[4, "station-info"]], "Status": [[4, "status"]], "Status Display Reference": [[7, null]], "Status Display Views Reference": [[8, null]], "Submitting the measurements": [[6, "submitting-the-measurements"]], "Syntax": [[4, "syntax"]]}, "docnames": ["api", "api_tutorial", "api_views", "data_access", "hisparc_maps", "index", "station_layout", "status_display", "status_display_views"], "envversion": {"sphinx": 63, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2}, "filenames": ["api.rst", "api_tutorial.rst", "api_views.rst", "data_access.rst", "hisparc_maps.rst", "index.rst", "station_layout.rst", "status_display.rst", "status_display_views.rst"], "indexentries": {"clusters() (in module publicdb.api.views)": [[2, "publicdb.api.views.clusters", false]], "config() (in module publicdb.api.views)": [[2, "publicdb.api.views.config", false]], "countries() (in module publicdb.api.views)": [[2, "publicdb.api.views.countries", false]], "create_plot_object() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.create_plot_object", false]], "get_cluster_dict() (in module publicdb.api.views)": [[2, "publicdb.api.views.get_cluster_dict", false]], "get_config_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_config_source", false]], "get_context_data() (networksummarydetailview method)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView.get_context_data", false]], "get_context_data() (summarydetailview method)": [[8, "publicdb.status_display.views.SummaryDetailView.get_context_data", false]], "get_country_dict() (in module publicdb.api.views)": [[2, "publicdb.api.views.get_country_dict", false]], "get_dataset_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_dataset_source", false]], "get_detector_timing_offsets() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_detector_timing_offsets", false]], "get_detector_timing_offsets_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_detector_timing_offsets_source", false]], "get_event_traces() (in module publicdb.api.views)": [[2, "publicdb.api.views.get_event_traces", false]], "get_eventtime_histogram_sources() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_eventtime_histogram_sources", false]], "get_eventtime_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_eventtime_source", false]], "get_focus() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_focus", false]], "get_gpslocations() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_gpslocations", false]], "get_histogram_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_histogram_source", false]], "get_object() (networksummarydetailview method)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView.get_object", false]], "get_object() (summarydetailview method)": [[8, "publicdb.status_display.views.SummaryDetailView.get_object", false]], "get_queryset() (networksummarydetailview method)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView.get_queryset", false]], "get_queryset() (summarydetailview method)": [[8, "publicdb.status_display.views.SummaryDetailView.get_queryset", false]], "get_redirect_url() (latestnetworksummaryredirectview method)": [[8, "publicdb.status_display.views.LatestNetworkSummaryRedirectView.get_redirect_url", false]], "get_redirect_url() (latestsummaryredirectview method)": [[8, "publicdb.status_display.views.LatestSummaryRedirectView.get_redirect_url", false]], "get_specific_config_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_specific_config_source", false]], "get_specific_dataset_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_specific_dataset_source", false]], "get_specific_histogram_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_specific_histogram_source", false]], "get_specific_network_histogram_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_specific_network_histogram_source", false]], "get_station_dict() (in module publicdb.api.views)": [[2, "publicdb.api.views.get_station_dict", false]], "get_station_layout_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_station_layout_source", false]], "get_station_timing_offsets() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_station_timing_offsets", false]], "get_station_timing_offsets_source() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.get_station_timing_offsets_source", false]], "get_subcluster_dict() (in module publicdb.api.views)": [[2, "publicdb.api.views.get_subcluster_dict", false]], "has_data() (in module publicdb.api.views)": [[2, "publicdb.api.views.has_data", false]], "help() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.help", false]], "http_method_names (networksummarydetailview attribute)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView.http_method_names", false]], "http_method_names (summarydetailview attribute)": [[8, "publicdb.status_display.views.SummaryDetailView.http_method_names", false]], "json_dict() (in module publicdb.api.views)": [[2, "publicdb.api.views.json_dict", false]], "latestnetworksummaryredirectview (class in publicdb.status_display.views)": [[8, "publicdb.status_display.views.LatestNetworkSummaryRedirectView", false]], "latestsummaryredirectview (class in publicdb.status_display.views)": [[8, "publicdb.status_display.views.LatestSummaryRedirectView", false]], "man() (in module publicdb.api.views)": [[2, "publicdb.api.views.man", false]], "module": [[0, "module-publicdb.api", false], [2, "module-publicdb.api.views", false], [7, "module-publicdb.status_display", false], [8, "module-publicdb.status_display.views", false]], "nav_calendar() (networksummarydetailview method)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView.nav_calendar", false]], "nav_calendar() (summarydetailview method)": [[8, "publicdb.status_display.views.SummaryDetailView.nav_calendar", false]], "nav_months() (networksummarydetailview method)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView.nav_months", false]], "nav_months() (summarydetailview method)": [[8, "publicdb.status_display.views.SummaryDetailView.nav_months", false]], "nav_years() (networksummarydetailview method)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView.nav_years", false]], "nav_years() (summarydetailview method)": [[8, "publicdb.status_display.views.SummaryDetailView.nav_years", false]], "network_status() (in module publicdb.api.views)": [[2, "publicdb.api.views.network_status", false]], "networksummarydetailview (class in publicdb.status_display.views)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView", false]], "none_to_nan() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.none_to_nan", false]], "num_events() (in module publicdb.api.views)": [[2, "publicdb.api.views.num_events", false]], "plot_config() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.plot_config", false]], "plot_dataset() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.plot_dataset", false]], "plot_histogram() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.plot_histogram", false]], "plot_timing_offsets() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.plot_timing_offsets", false]], "publicdb.api": [[0, "module-publicdb.api", false]], "publicdb.api.views": [[2, "module-publicdb.api.views", false]], "publicdb.status_display": [[7, "module-publicdb.status_display", false]], "publicdb.status_display.views": [[8, "module-publicdb.status_display.views", false]], "station() (in module publicdb.api.views)": [[2, "publicdb.api.views.station", false]], "station_config() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.station_config", false]], "station_has_config() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.station_has_config", false]], "station_has_data() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.station_has_data", false]], "station_latest() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.station_latest", false]], "station_status() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.station_status", false]], "stations() (in module publicdb.api.views)": [[2, "publicdb.api.views.stations", false]], "stations() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.stations", false]], "stations_by_country() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.stations_by_country", false]], "stations_by_name() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.stations_by_name", false]], "stations_by_number() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.stations_by_number", false]], "stations_by_status() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.stations_by_status", false]], "stations_on_map() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.stations_on_map", false]], "stations_with_data() (in module publicdb.api.views)": [[2, "publicdb.api.views.stations_with_data", false]], "stations_with_data() (in module publicdb.status_display.views)": [[8, "publicdb.status_display.views.stations_with_data", false]], "subclusters() (in module publicdb.api.views)": [[2, "publicdb.api.views.subclusters", false]], "summarydetailview (class in publicdb.status_display.views)": [[8, "publicdb.status_display.views.SummaryDetailView", false]], "template_name (networksummarydetailview attribute)": [[8, "publicdb.status_display.views.NetworkSummaryDetailView.template_name", false]], "template_name (summarydetailview attribute)": [[8, "publicdb.status_display.views.SummaryDetailView.template_name", false]], "validate_date() (in module publicdb.api.views)": [[2, "publicdb.api.views.validate_date", false]]}, "objects": {"publicdb": [[0, 0, 0, "-", "api"], [7, 0, 0, "-", "status_display"]], "publicdb.api": [[2, 0, 0, "-", "views"]], "publicdb.api.views": [[2, 1, 1, "", "clusters"], [2, 1, 1, "", "config"], [2, 1, 1, "", "countries"], [2, 1, 1, "", "get_cluster_dict"], [2, 1, 1, "", "get_country_dict"], [2, 1, 1, "", "get_event_traces"], [2, 1, 1, "", "get_station_dict"], [2, 1, 1, "", "get_subcluster_dict"], [2, 1, 1, "", "has_data"], [2, 1, 1, "", "json_dict"], [2, 1, 1, "", "man"], [2, 1, 1, "", "network_status"], [2, 1, 1, "", "num_events"], [2, 1, 1, "", "station"], [2, 1, 1, "", "stations"], [2, 1, 1, "", "stations_with_data"], [2, 1, 1, "", "subclusters"], [2, 1, 1, "", "validate_date"]], "publicdb.status_display": [[8, 0, 0, "-", "views"]], "publicdb.status_display.views": [[8, 2, 1, "", "LatestNetworkSummaryRedirectView"], [8, 2, 1, "", "LatestSummaryRedirectView"], [8, 2, 1, "", "NetworkSummaryDetailView"], [8, 2, 1, "", "SummaryDetailView"], [8, 1, 1, "", "create_plot_object"], [8, 1, 1, "", "get_config_source"], [8, 1, 1, "", "get_dataset_source"], [8, 1, 1, "", "get_detector_timing_offsets"], [8, 1, 1, "", "get_detector_timing_offsets_source"], [8, 1, 1, "", "get_eventtime_histogram_sources"], [8, 1, 1, "", "get_eventtime_source"], [8, 1, 1, "", "get_focus"], [8, 1, 1, "", "get_gpslocations"], [8, 1, 1, "", "get_histogram_source"], [8, 1, 1, "", "get_specific_config_source"], [8, 1, 1, "", "get_specific_dataset_source"], [8, 1, 1, "", "get_specific_histogram_source"], [8, 1, 1, "", "get_specific_network_histogram_source"], [8, 1, 1, "", "get_station_layout_source"], [8, 1, 1, "", "get_station_timing_offsets"], [8, 1, 1, "", "get_station_timing_offsets_source"], [8, 1, 1, "", "help"], [8, 1, 1, "", "none_to_nan"], [8, 1, 1, "", "plot_config"], [8, 1, 1, "", "plot_dataset"], [8, 1, 1, "", "plot_histogram"], [8, 1, 1, "", "plot_timing_offsets"], [8, 1, 1, "", "station_config"], [8, 1, 1, "", "station_has_config"], [8, 1, 1, "", "station_has_data"], [8, 1, 1, "", "station_latest"], [8, 1, 1, "", "station_status"], [8, 1, 1, "", "stations"], [8, 1, 1, "", "stations_by_country"], [8, 1, 1, "", "stations_by_name"], [8, 1, 1, "", "stations_by_number"], [8, 1, 1, "", "stations_by_status"], [8, 1, 1, "", "stations_on_map"], [8, 1, 1, "", "stations_with_data"]], "publicdb.status_display.views.LatestNetworkSummaryRedirectView": [[8, 3, 1, "", "get_redirect_url"]], "publicdb.status_display.views.LatestSummaryRedirectView": [[8, 3, 1, "", "get_redirect_url"]], "publicdb.status_display.views.NetworkSummaryDetailView": [[8, 3, 1, "", "get_context_data"], [8, 3, 1, "", "get_object"], [8, 3, 1, "", "get_queryset"], [8, 4, 1, "", "http_method_names"], [8, 3, 1, "", "nav_calendar"], [8, 3, 1, "", "nav_months"], [8, 3, 1, "", "nav_years"], [8, 4, 1, "", "template_name"]], "publicdb.status_display.views.SummaryDetailView": [[8, 3, 1, "", "get_context_data"], [8, 3, 1, "", "get_object"], [8, 3, 1, "", "get_queryset"], [8, 4, 1, "", "http_method_names"], [8, 3, 1, "", "nav_calendar"], [8, 3, 1, "", "nav_months"], [8, 3, 1, "", "nav_years"], [8, 4, 1, "", "template_name"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "function", "Python function"], "2": ["py", "class", "Python class"], "3": ["py", "method", "Python method"], "4": ["py", "attribute", "Python attribute"]}, "objtypes": {"0": "py:module", "1": "py:function", "2": "py:class", "3": "py:method", "4": "py:attribute"}, "terms": {"0": [1, 3, 4], "00": 3, "02": 3, "1": [1, 3], "10": 1, "1000": 1, "10882": 3, "11": [1, 3], "12": 3, "1372762802l": 3, "14720000326633453": 3, "2": [1, 3, 6], "20": 1, "2002": 8, "2004": 8, "201": 1, "2010": 1, "2011": 1, "2013": 3, "202": 3, "20kingdom": 4, "20park": 4, "3": [3, 6], "300": 4, "345": 3, "4": [1, 4, 6], "404": 2, "466307811l": 3, "4int16": 3, "4int32": 3, "5": 3, "501": [1, 3], "535": 3, "600": 4, "7": 3, "70000": 1, "78": 3, "798": 3, "8005": 4, "8103": 4, "854599952697754": 3, "999": 3, "A": 6, "And": 4, "But": 4, "By": 2, "For": [1, 2, 6], "If": [1, 2, 3, 4], "In": [1, 3], "It": [0, 1], "Not": 2, "On": [3, 4], "The": [0, 1, 3, 4, 5, 6, 7, 8], "Then": [1, 3, 4], "There": 3, "These": 6, "To": [1, 3, 4], "With": 1, "abl": 4, "about": [0, 1, 2, 3, 4, 6], "access": [0, 1, 5], "accomplish": 4, "activ": 4, "ad": 3, "administr": 5, "against": 1, "all": [1, 2, 3, 4, 6, 8], "alpha": 6, "also": [3, 4], "altitud": 6, "alwai": 3, "amsterdam": [1, 4], "an": [1, 2, 3, 4, 6], "analys": 6, "angl": 6, "anoth": 4, "antenn": [4, 6], "antenna": 6, "api": [3, 4, 5, 6], "append": 1, "applic": [0, 1, 3], "ar": [1, 3, 4, 6, 8], "arg": 8, "argument": [3, 8], "arrai": 3, "assign": 6, "attach": 1, "attr": 1, "avail": [1, 6, 8], "azimuth": 3, "base": [1, 4], "base_url": 1, "baselin": 2, "basic": 1, "becaus": 3, "been": [2, 3], "befor": [2, 6], "belong": [2, 8], "beta": 6, "between": [1, 3, 4, 6, 8], "bin": 8, "bodi": 1, "boolean": [2, 8], "born": 0, "box": 3, "bracket": 1, "bristol": 4, "browser": [1, 3], "button": [1, 3], "calendar": 8, "call": 8, "can": [1, 2, 3, 4, 5, 6, 8], "carto": 4, "center": 6, "chang": [1, 3], "check": [2, 3, 8], "checkbox": 3, "choos": [1, 3, 4], "chosen": [1, 6], "class": [1, 8], "click": [1, 3, 4], "clock": 6, "close": 4, "cluster": [0, 2, 4, 8], "cluster_id": 1, "cluster_numb": 2, "clusters_in_countri": 1, "code": [1, 4], "codeacademi": 1, "coincid": 8, "colleg": 3, "color": 4, "column": 3, "com": 1, "commun": 6, "compass": 5, "complet": 4, "config": [0, 1, 2, 8], "configur": [1, 2, 8], "consist": 2, "constructor": 8, "contain": [0, 1, 2, 8], "content": [0, 2, 4, 5, 7, 8], "context": 8, "convert": 3, "coordin": 5, "copi": 1, "correspond": 1, "cosmic": 2, "countri": [0, 1, 2, 4, 8], "country_id": 1, "country_numb": 2, "creat": [1, 2, 8], "create_plot_object": [7, 8], "csv": 3, "current": [4, 8], "d": [1, 3], "dai": [1, 2], "daili": 8, "dailyhistogram": 8, "daq": 2, "data": [0, 1, 2, 4, 5, 7, 8], "databas": [0, 3, 4], "dataset": 8, "date": [0, 1, 2, 3, 8], "datetim": [1, 3], "datetime64": 3, "datum": 1, "de": 6, "default": 8, "defin": [1, 3], "degre": 6, "delimit": 3, "denmark": [1, 4], "describ": 6, "desir": 2, "detail": 1, "detector": [4, 6], "determin": [4, 6], "dict": 8, "dictionari": [1, 2], "differ": 6, "displai": [1, 5], "distanc": 6, "do": [1, 3], "doc": 1, "document": 1, "doe": 1, "done": 5, "down": 1, "download": 5, "draw": 6, "drop": 1, "dtype": 3, "dure": [1, 2], "dutch": 6, "e": [1, 2, 3, 4, 6], "each": [1, 2, 4, 6], "easi": [0, 1, 3], "either": [1, 2, 6, 8], "embed": 5, "empti": 1, "enclos": 1, "end": [3, 8], "end_datum": 1, "ensched": 4, "entir": 2, "epoch": 2, "equip": 4, "error": 8, "esd": 3, "event": [1, 2, 3, 8], "eventtim": 8, "ever": 2, "everyon": 5, "exact": [4, 6], "exampl": [3, 4, 5, 6], "excel": 3, "explain": [4, 6], "explor": 1, "ext_timestamp": 2, "extend": 2, "extra": [4, 8], "fals": [2, 3], "famili": 1, "few": 1, "figur": 6, "file": [1, 3], "final": [1, 4], "find": [1, 2], "firefox": 3, "first": [3, 4, 5, 6], "fit": 4, "float32": 3, "focu": 4, "follow": [1, 3, 6, 8], "font": 1, "form": [5, 6], "format": [1, 3], "found": [2, 4], "four": 2, "framebord": 4, "framework": [1, 3], "from": [1, 2, 3, 6, 8], "full_url": 3, "function": 1, "g": [3, 4], "gather": 3, "gener": [1, 2, 8], "genfromtxt": 3, "get": [1, 2, 3, 8], "get_cluster_dict": [0, 2], "get_config_sourc": [7, 8], "get_context_data": [7, 8], "get_country_dict": [0, 2], "get_dataset_sourc": [7, 8], "get_detector_timing_offset": [7, 8], "get_detector_timing_offsets_sourc": [7, 8], "get_event_trac": [0, 2], "get_eventtime_histogram_sourc": [7, 8], "get_eventtime_sourc": [7, 8], "get_focu": [7, 8], "get_gpsloc": [7, 8], "get_histogram_sourc": [7, 8], "get_object": [7, 8], "get_queryset": [7, 8], "get_redirect_url": [7, 8], "get_specific_config_sourc": [7, 8], "get_specific_dataset_sourc": [7, 8], "get_specific_histogram_sourc": [7, 8], "get_specific_network_histogram_sourc": [7, 8], "get_stat": 1, "get_station_dict": [0, 2], "get_station_layout_sourc": [7, 8], "get_station_timing_offset": [7, 8], "get_station_timing_offsets_sourc": [7, 8], "get_subcluster_dict": [0, 2], "getjson": 1, "give": [1, 2, 4], "given": [2, 4, 8], "gp": [2, 4, 6, 8], "grai": 4, "green": 4, "h2": 1, "ha": [1, 2, 3, 4, 6, 8], "had": 1, "has_data": [0, 1, 2], "have": [1, 2, 4, 6], "head": 1, "height": [4, 6], "help": [7, 8], "here": [2, 4], "hisparc": [0, 1, 2, 3, 5], "histogram": 8, "histori": 8, "hour": [2, 3], "how": [1, 3, 6], "howev": [3, 6], "html": [1, 8], "http": [1, 3, 4], "http_method_nam": [7, 8], "httprespons": 2, "i": [1, 2, 3, 4, 5, 6, 8], "id": 1, "identifi": 2, "ifram": 4, "illustr": 6, "implement": 8, "import": [1, 3, 6], "importantli": 2, "includ": [1, 2, 3], "index": 5, "indic": [1, 4, 8], "individu": 2, "info": [1, 2], "infopakket": 6, "inform": [0, 1, 2, 3, 4, 6], "input": 1, "insert": 8, "instanc": 1, "instead": [1, 3], "int16": 3, "integ": 2, "integr": 3, "interfac": [0, 1, 5], "internet": 1, "its": [2, 4], "j": 1, "javascript": 5, "jqueri": 1, "jsfiddl": 1, "json": [1, 2], "json_dict": [0, 2], "jsparc": 3, "juli": 3, "just": 1, "kaj": 3, "karlsruh": 1, "kei": 1, "keyword": 8, "know": [1, 6], "kwarg": 8, "languag": 1, "latest": 2, "latestnetworksummaryredirectview": [7, 8], "latestsummaryredirectview": [7, 8], "layout": 5, "leafet": 4, "learn": 1, "level": 4, "librari": [1, 3, 4], "like": [1, 3], "line": 1, "link": [1, 3, 4, 8], "list": [2, 3, 8], "ll": 1, "load": 3, "locat": [2, 4, 6, 8], "long": 6, "longer": 4, "look": [3, 5, 8], "loop": 1, "made": [1, 6], "mai": [6, 8], "mail": 6, "main": [2, 4], "make": [1, 3, 6], "man": [0, 2], "mani": [1, 3], "map": [5, 8], "marker": 4, "match": [2, 8], "matplotlib": 1, "mean": 2, "measur": [1, 2, 5, 7], "menu": 1, "metadata": [1, 3], "meter": 6, "method": [1, 8], "min": 1, "modul": [1, 3, 5], "month": [1, 2, 8], "more": [1, 4, 6], "moreov": [4, 6], "most": [2, 8], "multipl": 4, "munk": 3, "n1": 3, "n2": 3, "n3": 3, "n4": 3, "name": [1, 2, 4, 8], "nanosecond": [2, 3], "nav_calendar": [7, 8], "nav_month": [7, 8], "nav_year": [7, 8], "neat": 1, "need": [0, 1, 3, 4, 6], "netherland": 4, "network": [1, 2, 4], "network_coincid": 8, "network_statu": [0, 2], "networkhistogram": 8, "networksummarydetailview": [7, 8], "new": [1, 6], "next": 6, "nice": 1, "nl": [1, 3, 4], "non": 2, "none": [2, 8], "none_to_nan": [7, 8], "north": 6, "notat": 1, "note": 4, "now": [1, 3, 8], "num_ev": [0, 1, 2], "number": [1, 2, 4, 8], "numpi": 3, "object": [1, 8], "octob": 1, "offlin": 4, "offset": 8, "often": 6, "old": 3, "onc": 1, "one": [1, 4], "onli": [2, 4], "onlin": 1, "open": 1, "openstreetmap": 4, "oper": [2, 4], "option": [1, 2, 3, 4], "order": 8, "organ": 4, "orient": 6, "other": [1, 8], "otherwis": [2, 8], "our": [4, 5], "out": [0, 2], "outsid": 2, "over": 1, "overridden": 8, "overview": [1, 2, 4], "own": 1, "p": 1, "packag": 3, "page": [1, 3, 4, 5, 8], "pair": 8, "paramet": [2, 8], "park": 4, "particular": 8, "pass": 3, "past": 1, "pattern": 8, "pc": 3, "period": 2, "perpar": 1, "place": [1, 3, 4], "pleas": 1, "plot": [1, 8], "plot_config": [7, 8], "plot_dataset": [7, 8], "plot_histogram": [7, 8], "plot_timing_offset": [7, 8], "popular": 1, "popup": 4, "posit": [1, 4, 6], "possibl": [1, 2, 4], "post": 3, "pre": 1, "presenc": 2, "present": 2, "previou": 8, "print": 3, "problem": 4, "process": 6, "program": [0, 1, 3], "project": 2, "properli": 4, "provid": [4, 7, 8], "public": [0, 3, 4], "pulseheight": 3, "pylab": 1, "python": 5, "queri": 3, "queryset": 8, "r": 6, "rai": 2, "rang": 2, "raw": [2, 4], "read": [1, 3], "recent": 8, "recogn": 3, "recommend": 1, "reconstruct": 6, "record": [2, 8], "red": 4, "redirect": 8, "ref_station_numb": 8, "refer": [1, 4, 5], "region": 4, "rel": [2, 6], "replac": 3, "request": [1, 2, 3, 8], "requir": [1, 3], "respond": 4, "respons": 1, "result": [1, 2, 4], "retriev": [1, 2, 8], "return": [2, 8], "review": 6, "right": 3, "rotat": 6, "s8": 3, "same": 6, "san": 1, "sapphir": [3, 4, 6], "schemat": 6, "school": 6, "scienc": 4, "scintil": [2, 6], "script": 1, "scroll": 4, "search": 5, "section": 6, "see": [1, 3, 6], "seen": 6, "select": [1, 3], "sent": [2, 6], "serif": 1, "server": 4, "set": [1, 2], "sever": [1, 3, 4], "sheet": 6, "should": [1, 2, 3], "show": [1, 3, 4, 8], "shower": [2, 8], "side": 6, "signific": 6, "simpli": 4, "simplifi": [0, 1], "sinc": 2, "singl": [2, 8], "some": 1, "specif": [2, 3, 4, 8], "specifi": 4, "src": [1, 4], "standard": 1, "start": [1, 3, 4, 8], "statement": 1, "static": 8, "station": [0, 1, 2, 3, 5, 7, 8], "station_config": [7, 8], "station_data": 8, "station_has_config": [7, 8], "station_has_data": [7, 8], "station_id": 1, "station_info": 1, "station_latest": [7, 8], "station_list": 1, "station_numb": [2, 8], "station_statu": [7, 8], "stationn": 2, "stations_by_countri": [7, 8], "stations_by_nam": [7, 8], "stations_by_numb": [7, 8], "stations_by_statu": [7, 8], "stations_on_map": [7, 8], "stations_with_data": [0, 2, 7, 8], "stationsplattegrond": 6, "statu": [2, 5], "status_displai": 8, "step": 1, "store": [3, 4], "str": 3, "stringifi": 1, "stringio": 3, "student": 6, "style": 1, "subclust": [0, 2, 4, 8], "subcluster_numb": 2, "subclusters_in_clust": 1, "submit": [1, 3, 5], "submitt": 6, "subtract": 2, "summari": [3, 7], "summarydetailview": [7, 8], "support": 8, "synchron": 4, "system": 6, "t": [3, 4], "t1": 3, "t2": 3, "t3": 3, "t4": 3, "t_trigger": 3, "tab": 3, "taken": 3, "tell": 1, "template_nam": [7, 8], "test": 2, "text": 1, "thei": 6, "thi": [1, 2, 3, 4, 6, 8], "thing": [1, 8], "those": 4, "through": [5, 6], "tile": 4, "time": [2, 3, 4, 8], "timedelta": 1, "timestamp": [2, 3], "total": 2, "trace": 2, "trigger": 8, "true": 2, "try": 1, "tupl": 8, "turn": 6, "tutori": [3, 5], "two": [1, 2], "type": [1, 2, 8], "u": [1, 6], "uint32": 3, "undefin": 1, "understand": 1, "understood": 1, "unit": [4, 6], "unix": 2, "unrespons": 4, "up": [0, 1, 3, 6, 8], "url": [1, 2, 3, 4, 8], "urlconf": 8, "urlencod": 3, "urllib": [1, 3], "urlopen": [1, 3], "us": [1, 3, 4, 6, 8], "user": 2, "utrecht": [1, 4], "val": 1, "valid": [2, 8], "validate_d": [0, 2], "valu": [1, 8], "var": 1, "variabl": 3, "verif": 6, "via": [1, 4, 5, 6], "view": [0, 5, 7], "visual": 4, "voltag": 8, "wa": 0, "wai": [1, 3, 6], "walk": 6, "want": [1, 3], "we": [1, 2, 3, 4, 6], "weather": [2, 3, 8], "web": 3, "webpag": [1, 7], "websit": [1, 4, 6], "week": 1, "what": 1, "when": [3, 4, 6], "which": [1, 2, 3, 4, 5, 6, 8], "while": 1, "width": 4, "window": [3, 4], "wise": 6, "within": 2, "without": [1, 2, 3], "work": [1, 3], "x": 8, "x_label": 8, "x_valu": 8, "y": 8, "y_label": 8, "y_seri": 8, "year": [1, 2, 8], "yellow": 4, "you": [1, 2, 3, 4], "your": [1, 3], "z": 6, "zaanstad": 4, "zenith": 3, "zoom": 4, "\u03b1": 6, "\u03b2": 6}, "titles": ["API Reference", "API Tutorial", "API Views Reference", "Data access", "HiSPARC maps", "Public Database documentation!", "HiSPARC station layout", "Status Display Reference", "Status Display Views Reference"], "titleterms": {"access": [3, 6], "api": [0, 1, 2], "cluster": 1, "compass": 6, "coordin": 6, "data": [3, 6], "databas": 5, "displai": [7, 8], "document": 5, "download": 3, "embed": 4, "exampl": 1, "first": 1, "form": 3, "hisparc": [4, 6], "indic": 5, "info": 4, "javascript": 1, "layout": 6, "list": 1, "look": 1, "map": 4, "measur": 6, "public": 5, "python": [1, 3], "refer": [0, 2, 7, 8], "sapphir": 1, "station": [4, 6], "statu": [4, 7, 8], "submit": 6, "syntax": 4, "tabl": 5, "tutori": 1, "via": 3, "view": [2, 8]}}) \ No newline at end of file diff --git a/station_layout.html b/station_layout.html new file mode 100644 index 000000000..2c109c46c --- /dev/null +++ b/station_layout.html @@ -0,0 +1,173 @@ + + + + + + + + HiSPARC station layout — Public Database 0.4 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

HiSPARC station layout

+

Each HiSPARC station has a GPS antenne and either 2 or 4 scintillator +detectors. This GPS is used to determine the exact location of the +station. However, the GPS is often not at the center of the station, +moreover, not all stations are oriented the same way, and the distances +between detector may differ. For reconstruction of the measured data it +is important to know the location of each detector, this section +explains how the location of the detectors can be measured and +communicated to us.

+
+

Compass coordinates

+

The coordinate system we have chosen for describing the position of +detectors is illustrated in the following figure.

+_images/coordinate_system.png + +

For each detector 3 (or 4) coordinates need to be determined:

+
    +
  • First the distance (r) from the GPS to the center of the +scintillator (in meters).

  • +
  • Next the alpha angle (α) which is the clock-wise turning angle +between North and the detector as seen from the GPS (in degrees).

  • +
  • A height (z) coordinate can be measured if there is a +significant altitude difference between the GPS antenna and the +detectors, or if the detectors are not at the same height. Up is +positive (in meters).

  • +
  • The rotation of the detector is described by the beta angle +(β), which is the clock-wise turning rotation of the long side +of the detector relative to North (in degrees).

  • +
+

For more information about the coordinate systems used in HiSPARC see: +Coordinate systems and units in HiSPARC.

+

For Dutch schools we have an assignment sheet in the infopakket which +walks students through the process of measuring the station layout: +De stationsplattegrond.

+
+
+

Submitting the measurements

+

New layouts can be submitted via the layout submit form. A verification e-mail will be sent +to the submitter. The submitted measurements will be reviewed before they are +made available on the website and via the API.

+
+
+

Accessing the data

+

The detector coordinates can be accessed via the API. +These can, for example, be used when analysing data or when making a schematic +drawing of the station layout.

+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/status_display.html b/status_display.html new file mode 100644 index 000000000..0738305bf --- /dev/null +++ b/status_display.html @@ -0,0 +1,191 @@ + + + + + + + + Status Display Reference — Public Database 0.4 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

Status Display Reference

+

Station Status Display

+

The Status Display provides webpages that display summaries of data measured +by stations.

+

Contents:

+
+ +
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/status_display_views.html b/status_display_views.html new file mode 100644 index 000000000..991195efa --- /dev/null +++ b/status_display_views.html @@ -0,0 +1,591 @@ + + + + + + + + Status Display Views Reference — Public Database 0.4 documentation + + + + + + + + + + + + + +
+
+
+
+ +
+

Status Display Views Reference

+
+
+class LatestNetworkSummaryRedirectView(**kwargs)
+

Show most recent coincidence data page

+

Constructor. Called in the URLconf; can contain helpful extra +keyword arguments, and other things.

+
+
+get_redirect_url(*args, **kwargs)
+

Return the URL redirect to. Keyword arguments from the URL pattern +match generating the redirect request are provided as kwargs to this +method.

+
+ +
+ +
+
+class LatestSummaryRedirectView(**kwargs)
+

Show most recent data for a particular station

+

Constructor. Called in the URLconf; can contain helpful extra +keyword arguments, and other things.

+
+
+get_redirect_url(*args, **kwargs)
+

Return the URL redirect to. Keyword arguments from the URL pattern +match generating the redirect request are provided as kwargs to this +method.

+
+ +
+ +
+
+class NetworkSummaryDetailView(**kwargs)
+

Constructor. Called in the URLconf; can contain helpful extra +keyword arguments, and other things.

+
+
+get_context_data(**kwargs)
+

Insert the single object into the context dict.

+
+ +
+
+get_object(queryset=None)
+

Get the object this request displays.

+
+ +
+
+get_queryset()
+

Return the QuerySet that will be used to look up the object.

+

This method is called by the default implementation of get_object() and +may not be called if get_object() is overridden.

+
+ +
+
+http_method_names = ['get']
+
+ +
+
+nav_calendar()
+

Create a month calendar with links

+
+ +
+
+nav_months()
+

Create list of months with links

+
+ +
+
+nav_years()
+

Create list of previous years

+
+ +
+
+template_name = 'status_display/network_coincidences.html'
+
+ +
+ +
+
+class SummaryDetailView(**kwargs)
+

Constructor. Called in the URLconf; can contain helpful extra +keyword arguments, and other things.

+
+
+get_context_data(**kwargs)
+

Insert the single object into the context dict.

+
+ +
+
+get_object(queryset=None)
+

Get the object this request displays.

+
+ +
+
+get_queryset()
+

Return the QuerySet that will be used to look up the object.

+

This method is called by the default implementation of get_object() and +may not be called if get_object() is overridden.

+
+ +
+
+http_method_names = ['get']
+
+ +
+
+nav_calendar()
+

Create a month calendar with links

+
+ +
+
+nav_months()
+

Create list of months with links

+
+ +
+
+nav_years()
+

Create list of previous years

+
+ +
+
+template_name = 'status_display/station_data.html'
+
+ +
+ +
+
+create_plot_object(x_values, y_series, x_label, y_label)
+
+ +
+
+get_config_source(station_number, type)
+

Get configuration data for a specific station

+
+
Parameters:
+
    +
  • station_number – station for which to get the configuration data.

  • +
  • type – the type of configuration data to get. The following +are supported: voltage, current, gps, trigger.

  • +
+
+
Returns:
+

list of lists containing the configuration history.

+
+
+
+ +
+
+get_dataset_source(date, type, station_number)
+

Get a dataset for a specific date and station

+
+
Parameters:
+
    +
  • date – the date for which to get the dataset.

  • +
  • type – the type of dataset to retrieve.

  • +
  • station_number – the station to which the data belongs.

  • +
+
+
Returns:
+

list of tuples containing (x, y) pairs.

+
+
+
+ +
+
+get_detector_timing_offsets(station_number)
+
+ +
+
+get_detector_timing_offsets_source(request, station_number)
+
+ +
+
+get_eventtime_histogram_sources(station_number, start, end)
+
+ +
+
+get_eventtime_source(request, station_number, start=None, end=None)
+

Get all eventtime data from start to end

+
+ +
+
+get_focus(country=None, cluster=None, subcluster=None)
+
+ +
+
+get_gpslocations(configs)
+

Get all valid GPS locations from the configs

+
+ +
+
+get_histogram_source(date, type, station_number=None)
+

Get histogram data for a specific date

+
+
Parameters:
+
    +
  • date – the date for which to get the histogram data.

  • +
  • type – the type of histogram to retrieve.

  • +
  • station_number – if None a NetworkHistogram is looked for, otherwise +a DailyHistogram for a specific station is looked for.

  • +
+
+
Returns:
+

list of tuples containing (bin, value) pairs.

+
+
+
+ +
+
+get_specific_config_source(request, station_number, type)
+
+ +
+
+get_specific_dataset_source(request, station_number, date, type)
+
+ +
+
+get_specific_histogram_source(request, station_number, date, type)
+

Get a station histogram for a specific date

+
+ +
+
+get_specific_network_histogram_source(request, date, type)
+
+ +
+
+get_station_layout_source(request, station_number)
+
+ +
+
+get_station_timing_offsets(ref_station_number, station_number)
+

Get all station timing offsets for a station pair

+
+
Parameters:
+

ref_station_number,station_number – station numbers.

+
+
Returns:
+

list of tuples with date, offset, and error.

+
+
+
+ +
+
+get_station_timing_offsets_source(request, ref_station_number, station_number)
+
+ +
+
+help(request)
+

Show the static help page

+
+ +
+
+none_to_nan(x)
+
+ +
+
+plot_config(type, configs)
+

Create a plot object from station configs

+
+ +
+
+plot_dataset(dataset)
+

Create a dataset plot object

+
+ +
+
+plot_histogram(histogram)
+

Create a histogram object

+
+ +
+
+plot_timing_offsets(station_number)
+

Create a plot object from station configs

+
+ +
+
+station_config(request, station_number)
+

Show configuration history for a particular station

+
+ +
+
+station_has_config(station)
+

Check if there is a valid configuration for the given station

+
+
Parameters:
+

station – Station object for which to check.

+
+
Returns:
+

boolean indicating if the station has a configuration available.

+
+
+
+ +
+
+station_has_data(station)
+

Check if there is valid event or weather data for the given station

+
+
Parameters:
+

station – Station object for which to check.

+
+
Returns:
+

boolean indicating if the station has recorded data, either +weather or shower, between 2002 and now.

+
+
+
+ +
+
+station_latest(request, station_number)
+

Show daily histograms for a particular station

+
+ +
+
+station_status(request, station_number)
+

Show data status for a particular station

+
+ +
+
+stations(request)
+

Show the default station list

+
+ +
+
+stations_by_country(request)
+

Show a list of stations, ordered by country, cluster and subcluster

+
+ +
+
+stations_by_name(request)
+

Show a list of stations, ordered by station name

+
+ +
+
+stations_by_number(request)
+

Show a list of stations, ordered by number

+
+ +
+
+stations_by_status(request)
+

Show a list of stations, ordered by status

+
+ +
+
+stations_on_map(request, country=None, cluster=None, subcluster=None)
+

Show all stations from a subcluster on a map

+
+ +
+
+stations_with_data()
+

Get list of station numbers with valid event or weather data

+
+
Returns:
+

list with station numbers for stations that recorded data, either +weather or shower, between 2004 and now.

+
+
+
+ +

Contents:

+
+
+
+ + +
+
+
+
+ +
+
+ + + + \ No newline at end of file